aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@chromium.org>2012-10-11 17:01:28 -0700
committerDerek Schuff <dschuff@chromium.org>2012-10-11 17:01:28 -0700
commit4db6bb7837c58641c4416e87643833bca4945841 (patch)
tree5f06f1dd5968c63c8e94cc077fd6016165ba0931
parent6b4efcb6bb663678c5cdd63a22e1ccc5ec6819f1 (diff)
parent2fa8af224ea026f9432e833fd6f42a216423a010 (diff)
Merge commit '2fa8af224ea026f9432e833fd6f42a216423a010'
Conflicts: lib/ExecutionEngine/JIT/JITEmitter.cpp lib/MC/MCELFStreamer.cpp lib/Target/ARM/ARMAsmPrinter.h lib/Target/X86/X86RegisterInfo.td lib/Target/X86/X86TargetMachine.cpp tools/llc/llc.cpp
-rw-r--r--CREDITS.TXT2
-rw-r--r--Makefile1
-rw-r--r--Makefile.config.in1
-rw-r--r--Makefile.rules35
-rw-r--r--autoconf/configure.ac5
-rw-r--r--bindings/ocaml/executionengine/llvm_executionengine.ml4
-rw-r--r--bindings/ocaml/executionengine/llvm_executionengine.mli2
-rw-r--r--bindings/ocaml/llvm/llvm.mli2
-rw-r--r--bindings/ocaml/target/llvm_target.ml26
-rw-r--r--bindings/ocaml/target/llvm_target.mli56
-rw-r--r--bindings/ocaml/target/target_ocaml.c30
-rwxr-xr-xcmake/modules/AddLLVM.cmake12
-rwxr-xr-xconfigure10
-rw-r--r--docs/AliasAnalysis.rst2
-rw-r--r--docs/CodeGenerator.rst18
-rw-r--r--docs/CodingStandards.rst21
-rw-r--r--docs/CompilerWriterInfo.html267
-rw-r--r--docs/CompilerWriterInfo.rst118
-rw-r--r--docs/ExtendingLLVM.html379
-rw-r--r--docs/ExtendingLLVM.rst306
-rw-r--r--docs/GarbageCollection.html4
-rw-r--r--docs/GettingStarted.html1760
-rw-r--r--docs/GettingStarted.rst1304
-rw-r--r--docs/GoldPlugin.html227
-rw-r--r--docs/GoldPlugin.rst186
-rw-r--r--docs/HowToSetUpLLVMStyleRTTI.rst281
-rw-r--r--docs/LangRef.html8
-rw-r--r--docs/LinkTimeOptimization.rst2
-rw-r--r--docs/ProgrammersManual.html27
-rw-r--r--docs/SourceLevelDebugging.html6
-rw-r--r--docs/WritingAnLLVMBackend.html10
-rw-r--r--docs/_themes/llvm-theme/static/llvm-theme.css3
-rw-r--r--docs/index.rst2
-rw-r--r--docs/programming.rst16
-rw-r--r--docs/subsystems.rst3
-rw-r--r--docs/tutorial/LangImpl4.html6
-rw-r--r--docs/tutorial/LangImpl5.html4
-rw-r--r--docs/tutorial/LangImpl6.html4
-rw-r--r--docs/tutorial/LangImpl7.html6
-rw-r--r--docs/tutorial/OCamlLangImpl4.html4
-rw-r--r--docs/tutorial/OCamlLangImpl5.html2
-rw-r--r--docs/tutorial/OCamlLangImpl6.html2
-rw-r--r--docs/tutorial/OCamlLangImpl7.html4
-rw-r--r--docs/userguides.rst3
-rw-r--r--examples/ExceptionDemo/ExceptionDemo.cpp4
-rw-r--r--examples/Kaleidoscope/Chapter4/toy.cpp4
-rw-r--r--examples/Kaleidoscope/Chapter5/toy.cpp4
-rw-r--r--examples/Kaleidoscope/Chapter6/toy.cpp4
-rw-r--r--examples/Kaleidoscope/Chapter7/toy.cpp4
-rw-r--r--examples/OCaml-Kaleidoscope/Chapter4/toy.ml2
-rw-r--r--examples/OCaml-Kaleidoscope/Chapter5/toy.ml2
-rw-r--r--examples/OCaml-Kaleidoscope/Chapter6/toy.ml2
-rw-r--r--examples/OCaml-Kaleidoscope/Chapter7/toy.ml2
-rw-r--r--include/llvm-c/Core.h2
-rw-r--r--include/llvm-c/Target.h36
-rw-r--r--include/llvm-c/TargetMachine.h2
-rw-r--r--include/llvm/ADT/MapVector.h11
-rw-r--r--include/llvm/ADT/SetVector.h92
-rw-r--r--include/llvm/ADT/Triple.h6
-rw-r--r--include/llvm/AddressingMode.h41
-rw-r--r--include/llvm/Analysis/AliasAnalysis.h12
-rw-r--r--include/llvm/Analysis/CaptureTracking.h2
-rw-r--r--include/llvm/Analysis/CodeMetrics.h8
-rw-r--r--include/llvm/Analysis/ConstantFolding.h16
-rw-r--r--include/llvm/Analysis/Dominators.h2
-rw-r--r--include/llvm/Analysis/IVUsers.h4
-rw-r--r--include/llvm/Analysis/InlineCost.h8
-rw-r--r--include/llvm/Analysis/InstructionSimplify.h54
-rw-r--r--include/llvm/Analysis/LazyValueInfo.h4
-rw-r--r--include/llvm/Analysis/Loads.h4
-rw-r--r--include/llvm/Analysis/MemoryBuiltins.h16
-rw-r--r--include/llvm/Analysis/MemoryDependenceAnalysis.h6
-rw-r--r--include/llvm/Analysis/PHITransAddr.h6
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h4
-rw-r--r--include/llvm/Analysis/ValueTracking.h26
-rw-r--r--include/llvm/Argument.h4
-rw-r--r--include/llvm/Attributes.h445
-rw-r--r--include/llvm/AttributesImpl.h (renamed from lib/VMCore/AttributesImpl.h)17
-rw-r--r--include/llvm/CallingConv.h20
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h6
-rw-r--r--include/llvm/CodeGen/CallingConvLower.h2
-rw-r--r--include/llvm/CodeGen/FastISel.h4
-rw-r--r--include/llvm/CodeGen/IntrinsicLowering.h6
-rw-r--r--include/llvm/CodeGen/MachineConstantPool.h6
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h2
-rw-r--r--include/llvm/CodeGen/MachineInstr.h17
-rw-r--r--include/llvm/CodeGen/MachineJumpTableInfo.h6
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h5
-rw-r--r--include/llvm/CodeGen/TargetSchedule.h1
-rw-r--r--include/llvm/DIBuilder.h7
-rw-r--r--include/llvm/DataLayout.h (renamed from include/llvm/Target/TargetData.h)173
-rw-r--r--include/llvm/DebugInfo.h2
-rw-r--r--include/llvm/DerivedTypes.h4
-rw-r--r--include/llvm/ExecutionEngine/ExecutionEngine.h8
-rw-r--r--include/llvm/ExecutionEngine/ObjectBuffer.h80
-rw-r--r--include/llvm/ExecutionEngine/ObjectImage.h61
-rw-r--r--include/llvm/ExecutionEngine/RuntimeDyld.h10
-rw-r--r--include/llvm/Function.h29
-rw-r--r--include/llvm/InitializePasses.h2
-rw-r--r--include/llvm/InstrTypes.h2
-rw-r--r--include/llvm/Instructions.h56
-rw-r--r--include/llvm/MC/MCAsmBackend.h7
-rw-r--r--include/llvm/MC/MCObjectFileInfo.h3
-rw-r--r--include/llvm/MC/MCObjectStreamer.h9
-rw-r--r--include/llvm/MC/MCParser/MCParsedAsmOperand.h2
-rw-r--r--include/llvm/MC/MCTargetAsmParser.h19
-rw-r--r--include/llvm/MC/SubtargetFeature.h4
-rw-r--r--include/llvm/Object/ELF.h33
-rw-r--r--include/llvm/Support/CallSite.h14
-rw-r--r--include/llvm/Support/CommandLine.h6
-rw-r--r--include/llvm/Support/TargetFolder.h6
-rw-r--r--include/llvm/TableGen/Main.h9
-rw-r--r--include/llvm/TableGen/Record.h80
-rw-r--r--include/llvm/TableGen/TableGenAction.h35
-rw-r--r--include/llvm/Target/Mangler.h9
-rw-r--r--include/llvm/Target/TargetLowering.h57
-rw-r--r--include/llvm/Target/TargetMachine.h4
-rw-r--r--include/llvm/Target/TargetSchedule.td13
-rw-r--r--include/llvm/Target/TargetSelectionDAGInfo.h6
-rw-r--r--include/llvm/Target/TargetSubtargetInfo.h6
-rw-r--r--include/llvm/Transforms/IPO/InlinerPass.h2
-rw-r--r--include/llvm/Transforms/Utils/AddrModeMatcher.h3
-rw-r--r--include/llvm/Transforms/Utils/BuildLibCalls.h32
-rw-r--r--include/llvm/Transforms/Utils/BypassSlowDivision.h2
-rw-r--r--include/llvm/Transforms/Utils/Cloning.h8
-rw-r--r--include/llvm/Transforms/Utils/Local.h16
-rw-r--r--include/llvm/Type.h4
-rw-r--r--include/llvm/User.h41
-rw-r--r--lib/Analysis/AliasAnalysis.cpp8
-rw-r--r--lib/Analysis/AliasSetTracker.cpp2
-rw-r--r--lib/Analysis/BasicAliasAnalysis.cpp22
-rw-r--r--lib/Analysis/CaptureTracking.cpp4
-rw-r--r--lib/Analysis/CodeMetrics.cpp10
-rw-r--r--lib/Analysis/ConstantFolding.cpp34
-rw-r--r--lib/Analysis/IVUsers.cpp4
-rw-r--r--lib/Analysis/InlineCost.cpp21
-rw-r--r--lib/Analysis/InstructionSimplify.cpp68
-rw-r--r--lib/Analysis/LazyValueInfo.cpp8
-rw-r--r--lib/Analysis/Lint.cpp8
-rw-r--r--lib/Analysis/Loads.cpp8
-rw-r--r--lib/Analysis/LoopDependenceAnalysis.cpp2
-rw-r--r--lib/Analysis/MemoryBuiltins.cpp16
-rw-r--r--lib/Analysis/MemoryDependenceAnalysis.cpp12
-rw-r--r--lib/Analysis/NoAliasAnalysis.cpp4
-rw-r--r--lib/Analysis/ScalarEvolution.cpp16
-rw-r--r--lib/Analysis/ScalarEvolutionExpander.cpp12
-rw-r--r--lib/Analysis/ValueTracking.cpp49
-rw-r--r--lib/AsmParser/LLLexer.cpp2
-rw-r--r--lib/AsmParser/LLParser.cpp105
-rw-r--r--lib/AsmParser/LLParser.h2
-rw-r--r--lib/AsmParser/LLToken.h1
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp2
-rw-r--r--lib/CodeGen/Analysis.cpp12
-rw-r--r--lib/CodeGen/AsmPrinter/ARMException.cpp2
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp60
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp4
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.cpp10
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp4
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfCFIException.cpp2
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp10
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp37
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.cpp4
-rw-r--r--lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp4
-rw-r--r--lib/CodeGen/AsmPrinter/Win64Exception.cpp2
-rw-r--r--lib/CodeGen/BranchFolding.cpp22
-rw-r--r--lib/CodeGen/CallingConvLower.cpp2
-rw-r--r--lib/CodeGen/CodePlacementOpt.cpp2
-rw-r--r--lib/CodeGen/EarlyIfConversion.cpp5
-rw-r--r--lib/CodeGen/ExecutionDepsFix.cpp9
-rw-r--r--lib/CodeGen/IntrinsicLowering.cpp2
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp15
-rw-r--r--lib/CodeGen/MachineBasicBlock.cpp2
-rw-r--r--lib/CodeGen/MachineBlockPlacement.cpp3
-rw-r--r--lib/CodeGen/MachineFunction.cpp16
-rw-r--r--lib/CodeGen/MachineInstr.cpp29
-rw-r--r--lib/CodeGen/MachineModuleInfo.cpp2
-rw-r--r--lib/CodeGen/MachineScheduler.cpp54
-rw-r--r--lib/CodeGen/MachineTraceMetrics.cpp60
-rw-r--r--lib/CodeGen/MachineTraceMetrics.h11
-rw-r--r--lib/CodeGen/Passes.cpp6
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp6
-rw-r--r--lib/CodeGen/RegAllocPBQP.cpp4
-rw-r--r--lib/CodeGen/RegisterCoalescer.cpp351
-rw-r--r--lib/CodeGen/ScheduleDAGInstrs.cpp102
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp446
-rw-r--r--lib/CodeGen/SelectionDAG/FastISel.cpp4
-rw-r--r--lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp6
-rw-r--r--lib/CodeGen/SelectionDAG/InstrEmitter.cpp6
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp18
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp22
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.cpp2
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp4
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp4
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp2
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp2
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h6
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGVLIW.cpp2
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp56
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp62
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h4
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp27
-rw-r--r--lib/CodeGen/SelectionDAG/TargetSelectionDAGInfo.cpp2
-rw-r--r--lib/CodeGen/SjLjEHPrepare.cpp4
-rw-r--r--lib/CodeGen/StackProtector.cpp8
-rw-r--r--lib/CodeGen/TailDuplication.cpp3
-rw-r--r--lib/CodeGen/TargetLoweringObjectFileImpl.cpp12
-rw-r--r--lib/CodeGen/TargetSchedule.cpp103
-rw-r--r--lib/ExecutionEngine/ExecutionEngine.cpp28
-rw-r--r--lib/ExecutionEngine/ExecutionEngineBindings.cpp2
-rw-r--r--lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp8
-rw-r--r--lib/ExecutionEngine/Interpreter/Interpreter.cpp2
-rw-r--r--lib/ExecutionEngine/Interpreter/Interpreter.h4
-rw-r--r--lib/ExecutionEngine/JIT/JIT.cpp14
-rw-r--r--lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp4
-rw-r--r--lib/ExecutionEngine/JIT/JITDwarfEmitter.h4
-rw-r--r--lib/ExecutionEngine/JIT/JITEmitter.cpp18
-rw-r--r--lib/ExecutionEngine/MCJIT/MCJIT.cpp36
-rw-r--r--lib/ExecutionEngine/MCJIT/MCJIT.h9
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp8
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h6
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h (renamed from lib/ExecutionEngine/RuntimeDyld/ObjectImage.h)135
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp16
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp89
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h9
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h17
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp6
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h2
-rw-r--r--lib/ExecutionEngine/TargetSelect.cpp9
-rw-r--r--lib/MC/MCAsmBackend.cpp7
-rw-r--r--lib/MC/MCELFStreamer.cpp51
-rw-r--r--lib/MC/MCMachOStreamer.cpp46
-rw-r--r--lib/MC/MCObjectFileInfo.cpp13
-rw-r--r--lib/MC/MCObjectStreamer.cpp38
-rw-r--r--lib/MC/MCParser/AsmParser.cpp3
-rw-r--r--lib/MC/MCSubtargetInfo.cpp2
-rw-r--r--lib/MC/SubtargetFeature.cpp33
-rw-r--r--lib/MC/WinCOFFStreamer.cpp42
-rw-r--r--lib/Support/CommandLine.cpp26
-rw-r--r--lib/Support/StringRef.cpp4
-rw-r--r--lib/Support/Triple.cpp11
-rw-r--r--lib/TableGen/CMakeLists.txt1
-rw-r--r--lib/TableGen/Main.cpp58
-rw-r--r--lib/TableGen/Record.cpp48
-rw-r--r--lib/TableGen/TGParser.cpp11
-rw-r--r--lib/TableGen/TGParser.h23
-rw-r--r--lib/TableGen/TableGenAction.cpp15
-rw-r--r--lib/Target/ARM/ARMAsmPrinter.cpp50
-rw-r--r--lib/Target/ARM/ARMAsmPrinter.h39
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.cpp3
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.cpp5
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp6
-rw-r--r--lib/Target/ARM/ARMConstantIslandPass.cpp4
-rw-r--r--lib/Target/ARM/ARMELFWriterInfo.cpp6
-rw-r--r--lib/Target/ARM/ARMFastISel.cpp14
-rw-r--r--lib/Target/ARM/ARMFrameLowering.cpp2
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp21
-rw-r--r--lib/Target/ARM/ARMInstrInfo.cpp2
-rw-r--r--lib/Target/ARM/ARMLoadStoreOptimizer.cpp6
-rw-r--r--lib/Target/ARM/ARMSelectionDAGInfo.cpp2
-rw-r--r--lib/Target/ARM/ARMTargetMachine.cpp4
-rw-r--r--lib/Target/ARM/ARMTargetMachine.h10
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp9
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp4
-rw-r--r--lib/Target/CMakeLists.txt1
-rw-r--r--lib/Target/CellSPU/SPUFrameLowering.cpp2
-rw-r--r--lib/Target/CellSPU/SPUSubtarget.h4
-rw-r--r--lib/Target/CellSPU/SPUTargetMachine.cpp2
-rw-r--r--lib/Target/CellSPU/SPUTargetMachine.h8
-rw-r--r--lib/Target/CppBackend/CPPTargetMachine.h4
-rw-r--r--lib/Target/Hexagon/HexagonAsmPrinter.cpp2
-rw-r--r--lib/Target/Hexagon/HexagonCallingConvLower.cpp2
-rw-r--r--lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp2
-rw-r--r--lib/Target/Hexagon/HexagonTargetMachine.cpp2
-rw-r--r--lib/Target/Hexagon/HexagonTargetMachine.h6
-rw-r--r--lib/Target/Hexagon/HexagonTargetObjectFile.cpp4
-rw-r--r--lib/Target/Hexagon/HexagonVarargsCallingConvention.h8
-rw-r--r--lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp5
-rw-r--r--lib/Target/MBlaze/MBlazeAsmPrinter.cpp2
-rw-r--r--lib/Target/MBlaze/MBlazeELFWriterInfo.cpp6
-rw-r--r--lib/Target/MBlaze/MBlazeFrameLowering.cpp2
-rw-r--r--lib/Target/MBlaze/MBlazeTargetMachine.cpp2
-rw-r--r--lib/Target/MBlaze/MBlazeTargetMachine.h8
-rw-r--r--lib/Target/MBlaze/MBlazeTargetObjectFile.cpp4
-rw-r--r--lib/Target/MSP430/MSP430FrameLowering.cpp2
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.cpp2
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.h2
-rw-r--r--lib/Target/MSP430/MSP430TargetMachine.cpp4
-rw-r--r--lib/Target/MSP430/MSP430TargetMachine.h6
-rw-r--r--lib/Target/Mangler.cpp4
-rw-r--r--lib/Target/Mips/AsmParser/MipsAsmParser.cpp530
-rw-r--r--lib/Target/Mips/CMakeLists.txt1
-rw-r--r--lib/Target/Mips/MCTargetDesc/CMakeLists.txt1
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsDirectObjLower.cpp (renamed from lib/Target/Mips/MipsDirectObjLower.cpp)63
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsDirectObjLower.h (renamed from lib/Target/Mips/MipsDirectObjLower.h)0
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp34
-rw-r--r--lib/Target/Mips/Mips16FrameLowering.cpp2
-rw-r--r--lib/Target/Mips/Mips16InstrInfo.td83
-rw-r--r--lib/Target/Mips/Mips64InstrInfo.td8
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.cpp19
-rw-r--r--lib/Target/Mips/MipsCodeEmitter.cpp6
-rw-r--r--lib/Target/Mips/MipsELFWriterInfo.cpp2
-rw-r--r--lib/Target/Mips/MipsFrameLowering.cpp2
-rw-r--r--lib/Target/Mips/MipsISelDAGToDAG.cpp32
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp6
-rw-r--r--lib/Target/Mips/MipsInstrFormats.td29
-rw-r--r--lib/Target/Mips/MipsInstrInfo.td21
-rw-r--r--lib/Target/Mips/MipsSEFrameLowering.cpp2
-rw-r--r--lib/Target/Mips/MipsTargetMachine.cpp2
-rw-r--r--lib/Target/Mips/MipsTargetMachine.h8
-rw-r--r--lib/Target/Mips/MipsTargetObjectFile.cpp4
-rw-r--r--lib/Target/NVPTX/NVPTXAllocaHoisting.h4
-rw-r--r--lib/Target/NVPTX/NVPTXAsmPrinter.cpp29
-rw-r--r--lib/Target/NVPTX/NVPTXISelLowering.cpp10
-rw-r--r--lib/Target/NVPTX/NVPTXLowerAggrCopies.cpp4
-rw-r--r--lib/Target/NVPTX/NVPTXLowerAggrCopies.h4
-rw-r--r--lib/Target/NVPTX/NVPTXTargetMachine.cpp4
-rw-r--r--lib/Target/NVPTX/NVPTXTargetMachine.h6
-rw-r--r--lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp6
-rw-r--r--lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp4
-rw-r--r--lib/Target/PowerPC/PPCAsmPrinter.cpp6
-rw-r--r--lib/Target/PowerPC/PPCFrameLowering.cpp5
-rw-r--r--lib/Target/PowerPC/PPCISelDAGToDAG.cpp23
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp339
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.h8
-rw-r--r--lib/Target/PowerPC/PPCInstr64Bit.td28
-rw-r--r--lib/Target/PowerPC/PPCInstrAltivec.td32
-rw-r--r--lib/Target/PowerPC/PPCInstrInfo.td83
-rw-r--r--lib/Target/PowerPC/PPCRegisterInfo.cpp2
-rw-r--r--lib/Target/PowerPC/PPCSubtarget.cpp2
-rw-r--r--lib/Target/PowerPC/PPCSubtarget.h4
-rw-r--r--lib/Target/PowerPC/PPCTargetMachine.cpp2
-rw-r--r--lib/Target/PowerPC/PPCTargetMachine.h6
-rw-r--r--lib/Target/README.txt2
-rw-r--r--lib/Target/Sparc/SparcFrameLowering.cpp2
-rw-r--r--lib/Target/Sparc/SparcISelLowering.cpp2
-rw-r--r--lib/Target/Sparc/SparcTargetMachine.cpp2
-rw-r--r--lib/Target/Sparc/SparcTargetMachine.h6
-rw-r--r--lib/Target/Target.cpp8
-rw-r--r--lib/Target/TargetELFWriterInfo.cpp2
-rw-r--r--lib/Target/TargetLoweringObjectFile.cpp4
-rw-r--r--lib/Target/TargetMachineC.cpp12
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp82
-rw-r--r--lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp27
-rw-r--r--lib/Target/X86/InstPrinter/X86ATTInstPrinter.h1
-rw-r--r--lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp35
-rw-r--r--lib/Target/X86/InstPrinter/X86IntelInstPrinter.h3
-rw-r--r--lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp4
-rw-r--r--lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp9
-rw-r--r--lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp115
-rw-r--r--lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h2
-rw-r--r--lib/Target/X86/X86.td4
-rw-r--r--lib/Target/X86/X86AsmPrinter.cpp98
-rw-r--r--lib/Target/X86/X86AsmPrinter.h33
-rw-r--r--lib/Target/X86/X86COFFMachineModuleInfo.h2
-rw-r--r--lib/Target/X86/X86CodeEmitter.cpp46
-rw-r--r--lib/Target/X86/X86ELFWriterInfo.cpp2
-rw-r--r--lib/Target/X86/X86FastISel.cpp38
-rw-r--r--lib/Target/X86/X86FrameLowering.cpp10
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp20
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp40
-rw-r--r--lib/Target/X86/X86ISelLowering.h2
-rw-r--r--lib/Target/X86/X86InstrCompiler.td34
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp14
-rw-r--r--lib/Target/X86/X86InstrInfo.td2
-rw-r--r--lib/Target/X86/X86MCInstLower.cpp4
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp38
-rw-r--r--lib/Target/X86/X86RegisterInfo.h8
-rw-r--r--lib/Target/X86/X86RegisterInfo.td500
-rw-r--r--lib/Target/X86/X86SelectionDAGInfo.cpp2
-rw-r--r--lib/Target/X86/X86Subtarget.cpp15
-rw-r--r--lib/Target/X86/X86Subtarget.h19
-rw-r--r--lib/Target/X86/X86TargetMachine.cpp12
-rw-r--r--lib/Target/X86/X86TargetMachine.h10
-rw-r--r--lib/Target/XCore/XCoreAsmPrinter.cpp4
-rw-r--r--lib/Target/XCore/XCoreFrameLowering.cpp13
-rw-r--r--lib/Target/XCore/XCoreISelLowering.cpp14
-rw-r--r--lib/Target/XCore/XCoreTargetMachine.cpp2
-rw-r--r--lib/Target/XCore/XCoreTargetMachine.h6
-rw-r--r--lib/Transforms/IPO/ArgumentPromotion.cpp3
-rw-r--r--lib/Transforms/IPO/ConstantMerge.cpp8
-rw-r--r--lib/Transforms/IPO/DeadArgumentElimination.cpp57
-rw-r--r--lib/Transforms/IPO/FunctionAttrs.cpp4
-rw-r--r--lib/Transforms/IPO/GlobalOpt.cpp38
-rw-r--r--lib/Transforms/IPO/InlineAlways.cpp6
-rw-r--r--lib/Transforms/IPO/InlineSimple.cpp4
-rw-r--r--lib/Transforms/IPO/Inliner.cpp17
-rw-r--r--lib/Transforms/IPO/MergeFunctions.cpp26
-rw-r--r--lib/Transforms/IPO/PassManagerBuilder.cpp2
-rw-r--r--lib/Transforms/IPO/PruneEH.cpp8
-rw-r--r--lib/Transforms/InstCombine/InstCombine.h8
-rw-r--r--lib/Transforms/InstCombine/InstCombineAddSub.cpp2
-rw-r--r--lib/Transforms/InstCombine/InstCombineCalls.cpp33
-rw-r--r--lib/Transforms/InstCombine/InstCombineCasts.cpp6
-rw-r--r--lib/Transforms/InstCombine/InstCombineCompares.cpp4
-rw-r--r--lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp18
-rw-r--r--lib/Transforms/InstCombine/InstCombineMulDivRem.cpp4
-rw-r--r--lib/Transforms/InstCombine/InstCombinePHI.cpp2
-rw-r--r--lib/Transforms/InstCombine/InstCombineSelect.cpp2
-rw-r--r--lib/Transforms/InstCombine/InstCombineShifts.cpp2
-rw-r--r--lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp2
-rw-r--r--lib/Transforms/InstCombine/InstructionCombining.cpp8
-rw-r--r--lib/Transforms/Instrumentation/AddressSanitizer.cpp14
-rw-r--r--lib/Transforms/Instrumentation/BoundsChecking.cpp8
-rw-r--r--lib/Transforms/Instrumentation/GCOVProfiling.cpp8
-rw-r--r--lib/Transforms/Instrumentation/ThreadSanitizer.cpp34
-rw-r--r--lib/Transforms/Scalar/CodeGenPrepare.cpp20
-rw-r--r--lib/Transforms/Scalar/ConstantProp.cpp4
-rw-r--r--lib/Transforms/Scalar/DeadStoreElimination.cpp16
-rw-r--r--lib/Transforms/Scalar/EarlyCSE.cpp112
-rw-r--r--lib/Transforms/Scalar/GVN.cpp30
-rw-r--r--lib/Transforms/Scalar/GlobalMerge.cpp10
-rw-r--r--lib/Transforms/Scalar/IndVarSimplify.cpp19
-rw-r--r--lib/Transforms/Scalar/JumpThreading.cpp6
-rw-r--r--lib/Transforms/Scalar/LICM.cpp6
-rw-r--r--lib/Transforms/Scalar/LoopIdiomRecognize.cpp8
-rw-r--r--lib/Transforms/Scalar/LoopInstSimplify.cpp4
-rw-r--r--lib/Transforms/Scalar/LoopStrengthReduce.cpp15
-rw-r--r--lib/Transforms/Scalar/LoopUnrollPass.cpp9
-rw-r--r--lib/Transforms/Scalar/LoopUnswitch.cpp3
-rw-r--r--lib/Transforms/Scalar/MemCpyOptimizer.cpp66
-rw-r--r--lib/Transforms/Scalar/NaClCcRewrite.cpp7
-rw-r--r--lib/Transforms/Scalar/ObjCARC.cpp36
-rw-r--r--lib/Transforms/Scalar/SCCP.cpp10
-rw-r--r--lib/Transforms/Scalar/SROA.cpp1084
-rw-r--r--lib/Transforms/Scalar/Scalar.cpp2
-rw-r--r--lib/Transforms/Scalar/ScalarReplAggregates.cpp20
-rw-r--r--lib/Transforms/Scalar/SimplifyCFGPass.cpp6
-rw-r--r--lib/Transforms/Scalar/SimplifyLibCalls.cpp36
-rw-r--r--lib/Transforms/Utils/AddrModeMatcher.cpp4
-rw-r--r--lib/Transforms/Utils/BasicBlockUtils.cpp2
-rw-r--r--lib/Transforms/Utils/BuildLibCalls.cpp34
-rw-r--r--lib/Transforms/Utils/BypassSlowDivision.cpp23
-rw-r--r--lib/Transforms/Utils/CloneFunction.cpp6
-rw-r--r--lib/Transforms/Utils/InlineFunction.cpp4
-rw-r--r--lib/Transforms/Utils/Local.cpp10
-rw-r--r--lib/Transforms/Utils/SimplifyCFG.cpp58
-rw-r--r--lib/Transforms/Utils/SimplifyIndVar.cpp6
-rw-r--r--lib/Transforms/Utils/SimplifyInstructions.cpp4
-rw-r--r--lib/Transforms/Vectorize/BBVectorize.cpp8
-rw-r--r--lib/VMCore/AsmWriter.cpp18
-rw-r--r--lib/VMCore/Attributes.cpp310
-rw-r--r--lib/VMCore/CMakeLists.txt1
-rw-r--r--lib/VMCore/ConstantFold.cpp2
-rw-r--r--lib/VMCore/DIBuilder.cpp13
-rw-r--r--lib/VMCore/DataLayout.cpp (renamed from lib/Target/TargetData.cpp)216
-rw-r--r--lib/VMCore/DebugInfo.cpp10
-rw-r--r--lib/VMCore/Function.cpp15
-rw-r--r--lib/VMCore/Instructions.cpp28
-rw-r--r--lib/VMCore/LLVMContextImpl.h2
-rw-r--r--lib/VMCore/Value.cpp2
-rw-r--r--lib/VMCore/Verifier.cpp126
-rw-r--r--projects/sample/Makefile.llvm.rules4
-rw-r--r--runtime/libprofile/Makefile10
-rw-r--r--test/Analysis/Profiling/load-branch-weights-ifs.ll2
-rw-r--r--test/Analysis/Profiling/load-branch-weights-loops.ll2
-rw-r--r--test/Analysis/Profiling/load-branch-weights-switches.ll2
-rw-r--r--test/Assembler/2008-09-02-FunctionNotes2.ll2
-rw-r--r--test/Bindings/Ocaml/ipo_opts.ml6
-rw-r--r--test/Bindings/Ocaml/scalar_opts.ml6
-rw-r--r--test/Bindings/Ocaml/target.ml6
-rw-r--r--test/CodeGen/ARM/coalesce-subregs.ll27
-rw-r--r--test/CodeGen/ARM/darwin-section-order.ll21
-rw-r--r--test/CodeGen/ARM/deps-fix.ll22
-rw-r--r--test/CodeGen/CellSPU/icmp16.ll4
-rw-r--r--test/CodeGen/Mips/mul.ll17
-rw-r--r--test/CodeGen/Mips/mulll.ll21
-rw-r--r--test/CodeGen/Mips/mulull.ll21
-rw-r--r--test/CodeGen/Mips/stldst.ll41
-rw-r--r--test/CodeGen/PowerPC/ppc64-toc.ll136
-rw-r--r--test/CodeGen/PowerPC/vec_cmp.ll191
-rw-r--r--test/CodeGen/PowerPC/vec_conv.ll57
-rwxr-xr-xtest/CodeGen/SPARC/2011-01-11-CC.ll2
-rw-r--r--test/CodeGen/X86/2012-10-02-DAGCycle.ll52
-rw-r--r--test/CodeGen/X86/2012-10-03-DAGCycle.ll31
-rw-r--r--test/CodeGen/X86/MergeConsecutiveStores.ll305
-rw-r--r--test/CodeGen/X86/cmov-fp.ll451
-rw-r--r--test/CodeGen/X86/early-ifcvt.ll77
-rw-r--r--test/CodeGen/X86/fast-isel-x86-64.ll13
-rw-r--r--test/CodeGen/X86/ms-inline-asm.ll14
-rw-r--r--test/CodeGen/X86/pr13899.ll58
-rw-r--r--test/CodeGen/X86/red-zone2.ll7
-rw-r--r--test/CodeGen/X86/smul-with-overflow.ll14
-rw-r--r--test/DebugInfo/X86/DW_AT_byte_size.ll3
-rw-r--r--test/DebugInfo/X86/enum-fwd-decl.ll16
-rw-r--r--test/DebugInfo/X86/prologue-stack.ll35
-rw-r--r--test/ExecutionEngine/2002-12-16-ArgTest.ll1
-rw-r--r--test/ExecutionEngine/MCJIT/2002-12-16-ArgTest.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2003-01-04-ArgumentBug.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2003-01-04-LoopTest.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2003-01-04-PhiTest.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2003-01-09-SARTest.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2003-01-10-FUCOM.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2003-01-15-AlignmentTest.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2003-05-06-LivenessClobber.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2003-05-07-ArgumentTest.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2003-05-11-PHIRegAllocBug.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2003-06-04-bzip2-bug.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2003-06-05-PHIBug.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2003-08-15-AllocaAssertion.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2003-08-21-EnvironmentTest.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2003-08-23-RegisterAllocatePhysReg.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2003-10-18-PHINode-ConstantExpr-CondCode-Failure.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2005-12-02-TailCallBug.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2007-12-10-APIntLoadStore.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2008-06-05-APInt-OverAShr.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/2010-01-15-UndefValue.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/fpbitcast.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/hello.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/hello2.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/lit.local.cfg2
-rw-r--r--test/ExecutionEngine/MCJIT/pr13727.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/simplesttest.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/simpletest.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/stubs.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-arith.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-branch.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-call-no-external-funcs.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-call.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-cast.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-common-symbols.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-constantexpr.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-fp-no-external-funcs.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-fp.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-global-init-nonzero.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-global.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-loadstore.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-local.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-logical.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-loop.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-phi.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-ptr-reloc.ll16
-rw-r--r--test/ExecutionEngine/MCJIT/test-ret.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-return.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-setcond-fp.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-setcond-int.ll2
-rw-r--r--test/ExecutionEngine/MCJIT/test-shift.ll2
-rw-r--r--test/ExecutionEngine/test-fp-no-external-funcs.ll1
-rw-r--r--test/ExecutionEngine/test-fp.ll1
-rw-r--r--test/Instrumentation/ThreadSanitizer/atomic.ll80
-rw-r--r--test/MC/MachO/lit.local.cfg2
-rw-r--r--test/MC/MachO/x86-data-in-code.ll108
-rw-r--r--test/MC/Mips/mips-expansions.s14
-rw-r--r--test/MC/Mips/mips-fpu-instructions.s16
-rw-r--r--test/MC/Mips/mips_directives.s8
-rw-r--r--test/Makefile5
-rw-r--r--test/Other/ResponseFile.ll9
-rw-r--r--test/Other/spir_cc.ll13
-rw-r--r--test/Transforms/DeadArgElim/dbginfo.ll64
-rw-r--r--test/Transforms/EarlyCSE/commute.ll66
-rw-r--r--test/Transforms/IndVarSimplify/2004-04-05-InvokeCastCrash.ll4
-rw-r--r--test/Transforms/IndVarSimplify/crash.ll26
-rw-r--r--test/Transforms/InstCombine/align-addr.ll16
-rw-r--r--test/Transforms/InstCombine/and-fcmp.ll2
-rw-r--r--test/Transforms/MemCpyOpt/2008-03-13-ReturnSlotBitcast.ll4
-rw-r--r--test/Transforms/MemCpyOpt/align.ll24
-rw-r--r--test/Transforms/SROA/alignment.ll127
-rw-r--r--test/Transforms/SROA/basictest.ll81
-rw-r--r--test/Transforms/SROA/big-endian.ll108
-rw-r--r--test/Transforms/SROA/fca.ll2
-rw-r--r--test/Transforms/SROA/phi-and-select.ll26
-rw-r--r--test/Transforms/SROA/vector-promotion.ll2
-rw-r--r--test/Transforms/SimplifyCFG/phi-undef-loadstore.ll28
-rw-r--r--test/Transforms/SimplifyCFG/switch_to_lookup_table.ll24
-rw-r--r--test/lit.cfg12
-rw-r--r--tools/bugpoint/ExtractFunction.cpp2
-rw-r--r--tools/bugpoint/OptimizerDriver.cpp2
-rw-r--r--tools/llc/llc.cpp10
-rw-r--r--tools/lli/lli.cpp12
-rw-r--r--tools/llvm-config/Makefile2
-rw-r--r--tools/llvm-extract/llvm-extract.cpp4
-rw-r--r--tools/llvm-rtdyld/llvm-rtdyld.cpp8
-rw-r--r--tools/lto/LTOCodeGenerator.cpp10
-rw-r--r--tools/lto/LTOModule.cpp4
-rw-r--r--tools/lto/Makefile8
-rw-r--r--tools/opt/opt.cpp12
-rw-r--r--unittests/ADT/StringRefTest.cpp23
-rw-r--r--unittests/ExecutionEngine/CMakeLists.txt1
-rw-r--r--unittests/ExecutionEngine/JIT/JITTest.cpp15
-rw-r--r--unittests/ExecutionEngine/MCJIT/CMakeLists.txt25
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITTest.cpp226
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITTestBase.h245
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITTests.def1
-rw-r--r--unittests/ExecutionEngine/MCJIT/Makefile18
-rw-r--r--unittests/ExecutionEngine/MCJIT/SectionMemoryManager.cpp135
-rw-r--r--unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h117
-rw-r--r--unittests/ExecutionEngine/Makefile2
-rw-r--r--unittests/Support/CMakeLists.txt1
-rw-r--r--unittests/Support/MemoryBufferTest.cpp99
-rw-r--r--unittests/VMCore/InstructionsTest.cpp4
-rw-r--r--unittests/VMCore/PassManagerTest.cpp24
-rw-r--r--utils/TableGen/AsmMatcherEmitter.cpp100
-rw-r--r--utils/TableGen/CallingConvEmitter.cpp4
-rw-r--r--utils/TableGen/CodeGenSchedule.cpp400
-rw-r--r--utils/TableGen/CodeGenSchedule.h30
-rw-r--r--utils/TableGen/FixedLenDecoderEmitter.cpp2
-rw-r--r--utils/TableGen/SetTheory.cpp6
-rw-r--r--utils/TableGen/SubtargetEmitter.cpp30
-rw-r--r--utils/TableGen/TableGen.cpp159
598 files changed, 12436 insertions, 7690 deletions
diff --git a/CREDITS.TXT b/CREDITS.TXT
index b5aa2580e1..0257918258 100644
--- a/CREDITS.TXT
+++ b/CREDITS.TXT
@@ -17,7 +17,7 @@ D: The Sparc64 backend, provider of much wisdom, and motivator for LLVM
N: Owen Anderson
E: resistor@mac.com
D: LCSSA pass and related LoopUnswitch work
-D: GVNPRE pass, TargetData refactoring, random improvements
+D: GVNPRE pass, DataLayout refactoring, random improvements
N: Henrik Bach
D: MingW Win32 API portability layer
diff --git a/Makefile b/Makefile
index 49e4b24ebf..93837bbc60 100644
--- a/Makefile
+++ b/Makefile
@@ -82,6 +82,7 @@ ifeq ($(MAKECMDGOALS),install-clang)
endif
ifeq ($(MAKECMDGOALS),clang-only)
+ BUILD_CLANG_ONLY := YES
DIRS := $(filter-out tools docs unittests, $(DIRS)) \
tools/clang tools/lto
OPTIONAL_DIRS :=
diff --git a/Makefile.config.in b/Makefile.config.in
index e3bd2a207a..b4ecea631e 100644
--- a/Makefile.config.in
+++ b/Makefile.config.in
@@ -61,6 +61,7 @@ endif
prefix := @prefix@
PROJ_prefix := $(prefix)
+program_prefix := @program_prefix@
PROJ_VERSION := $(LLVMVersion)
else
ifndef PROJ_SRC_ROOT
diff --git a/Makefile.rules b/Makefile.rules
index 60064dbd1c..49bdbe2a23 100644
--- a/Makefile.rules
+++ b/Makefile.rules
@@ -631,19 +631,24 @@ endif
# Adjust linker flags for building an executable
ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
-ifneq ($(HOST_OS), Darwin)
-ifdef TOOLNAME
- LD.Flags += $(RPATH) -Wl,'$$ORIGIN/../lib'
- ifdef EXAMPLE_TOOL
- LD.Flags += $(RPATH) -Wl,$(ExmplDir) $(DynamicFlag)
- else
- LD.Flags += $(RPATH) -Wl,$(ToolDir) $(DynamicFlag)
+ ifneq ($(HOST_OS), Darwin)
+ ifdef TOOLNAME
+ LD.Flags += $(RPATH) -Wl,'$$ORIGIN/../lib'
+ ifdef EXAMPLE_TOOL
+ LD.Flags += $(RPATH) -Wl,$(ExmplDir) $(DynamicFlag)
+ else
+ LD.Flags += $(RPATH) -Wl,$(ToolDir) $(DynamicFlag)
+ endif
endif
-endif
else
-ifneq ($(DARWIN_MAJVERS),4)
- LD.Flags += $(RPATH) -Wl,@executable_path/../lib
-endif
+ ifneq ($(DARWIN_MAJVERS),4)
+ LD.Flags += $(RPATH) -Wl,@executable_path/../lib
+ endif
+ ifeq ($(RC_BUILDIT),YES)
+ ObjDir := $(shell mkdir -p ${OBJROOT}/dSYMs)
+ TempFile := $(shell mktemp ${ObjDir}/llvm-lto.XXXXXX)
+ LD.Flags += -Wl,-object_path_lto -Wl,$(TempFile)
+ endif
endif
endif
@@ -1543,7 +1548,7 @@ ifneq ($(strip $(ToolAliasBuildPath)),)
$(ToolAliasBuildPath): $(ToolBuildPath)
$(Echo) Creating $(BuildMode) Alias $(TOOLALIAS) $(StripWarnMsg)
$(Verb) $(RM) -f $(ToolAliasBuildPath)
- $(Verb) $(AliasTool) $(TOOLEXENAME) $(ToolAliasBuildPath)
+ $(Verb) $(AliasTool) $(notdir $(ToolBuildPath)) $(ToolAliasBuildPath)
$(Echo) ======= Finished Creating $(BuildMode) Alias $(TOOLALIAS) \
$(StripWarnMsg)
endif
@@ -1560,7 +1565,7 @@ ToolBinDir = $(DESTDIR)$(PROJ_internal_prefix)/bin
else
ToolBinDir = $(DESTDIR)$(PROJ_bindir)
endif
-DestTool = $(ToolBinDir)/$(TOOLEXENAME)
+DestTool = $(ToolBinDir)/$(program_prefix)$(TOOLEXENAME)
install-local:: $(DestTool)
@@ -1575,14 +1580,14 @@ uninstall-local::
# TOOLALIAS install.
ifdef TOOLALIAS
-DestToolAlias = $(ToolBinDir)/$(TOOLALIAS)$(EXEEXT)
+DestToolAlias = $(ToolBinDir)/$(program_prefix)$(TOOLALIAS)$(EXEEXT)
install-local:: $(DestToolAlias)
$(DestToolAlias): $(DestTool)
$(Echo) Installing $(BuildMode) $(DestToolAlias)
$(Verb) $(RM) -f $(DestToolAlias)
- $(Verb) $(AliasTool) $(TOOLEXENAME) $(DestToolAlias)
+ $(Verb) $(AliasTool) $(notdir $(DestTool)) $(DestToolAlias)
uninstall-local::
$(Echo) Uninstalling $(BuildMode) $(DestToolAlias)
diff --git a/autoconf/configure.ac b/autoconf/configure.ac
index 12dd5ea783..414e5bf5f1 100644
--- a/autoconf/configure.ac
+++ b/autoconf/configure.ac
@@ -1714,6 +1714,11 @@ fi
dnl OCaml findlib META file
AC_CONFIG_FILES([bindings/ocaml/llvm/META.llvm])
+dnl Add --program-prefix value to Makefile.rules. Already an ARG variable.
+test "x$program_prefix" = "xNONE" && program_prefix=""
+AC_SUBST([program_prefix])
+
+
dnl Do special configuration of Makefiles
AC_CONFIG_COMMANDS([setup],,[llvm_src="${srcdir}"])
AC_CONFIG_MAKEFILE(Makefile)
diff --git a/bindings/ocaml/executionengine/llvm_executionengine.ml b/bindings/ocaml/executionengine/llvm_executionengine.ml
index a8535b2464..b6178dc055 100644
--- a/bindings/ocaml/executionengine/llvm_executionengine.ml
+++ b/bindings/ocaml/executionengine/llvm_executionengine.ml
@@ -83,8 +83,8 @@ module ExecutionEngine = struct
external free_machine_code: Llvm.llvalue -> t -> unit
= "llvm_ee_free_machine_code"
- external target_data: t -> Llvm_target.TargetData.t
- = "LLVMGetExecutionEngineTargetData"
+ external target_data: t -> Llvm_target.DataLayout.t
+ = "LLVMGetExecutionEngineDataLayout"
(* The following are not bound. Patches are welcome.
diff --git a/bindings/ocaml/executionengine/llvm_executionengine.mli b/bindings/ocaml/executionengine/llvm_executionengine.mli
index 166b7bcddc..0b06078bad 100644
--- a/bindings/ocaml/executionengine/llvm_executionengine.mli
+++ b/bindings/ocaml/executionengine/llvm_executionengine.mli
@@ -155,7 +155,7 @@ module ExecutionEngine: sig
(** [target_data ee] is the target data owned by the execution engine
[ee]. *)
- val target_data : t -> Llvm_target.TargetData.t
+ val target_data : t -> Llvm_target.DataLayout.t
end
diff --git a/bindings/ocaml/llvm/llvm.mli b/bindings/ocaml/llvm/llvm.mli
index 96448ccd96..eb6c88355a 100644
--- a/bindings/ocaml/llvm/llvm.mli
+++ b/bindings/ocaml/llvm/llvm.mli
@@ -375,7 +375,7 @@ val module_context : llmodule -> llcontext
val classify_type : lltype -> TypeKind.t
(** [type_is_sized ty] returns whether the type has a size or not.
- * If it doesn't then it is not safe to call the [TargetData::] methods on it.
+ * If it doesn't then it is not safe to call the [DataLayout::] methods on it.
* *)
val type_is_sized : lltype -> bool
diff --git a/bindings/ocaml/target/llvm_target.ml b/bindings/ocaml/target/llvm_target.ml
index 49940eec48..f4891e2b83 100644
--- a/bindings/ocaml/target/llvm_target.ml
+++ b/bindings/ocaml/target/llvm_target.ml
@@ -13,7 +13,7 @@ module Endian = struct
| Little
end
-module TargetData = struct
+module DataLayout = struct
type t
external create : string -> t = "llvm_targetdata_create"
@@ -23,20 +23,20 @@ module TargetData = struct
external dispose : t -> unit = "llvm_targetdata_dispose"
end
-external byte_order : TargetData.t -> Endian.t = "llvm_byte_order"
-external pointer_size : TargetData.t -> int = "llvm_pointer_size"
-external intptr_type : TargetData.t -> Llvm.lltype = "LLVMIntPtrType"
-external size_in_bits : TargetData.t -> Llvm.lltype -> Int64.t
+external byte_order : DataLayout.t -> Endian.t = "llvm_byte_order"
+external pointer_size : DataLayout.t -> int = "llvm_pointer_size"
+external intptr_type : DataLayout.t -> Llvm.lltype = "LLVMIntPtrType"
+external size_in_bits : DataLayout.t -> Llvm.lltype -> Int64.t
= "llvm_size_in_bits"
-external store_size : TargetData.t -> Llvm.lltype -> Int64.t = "llvm_store_size"
-external abi_size : TargetData.t -> Llvm.lltype -> Int64.t = "llvm_abi_size"
-external abi_align : TargetData.t -> Llvm.lltype -> int = "llvm_abi_align"
-external stack_align : TargetData.t -> Llvm.lltype -> int = "llvm_stack_align"
-external preferred_align : TargetData.t -> Llvm.lltype -> int
+external store_size : DataLayout.t -> Llvm.lltype -> Int64.t = "llvm_store_size"
+external abi_size : DataLayout.t -> Llvm.lltype -> Int64.t = "llvm_abi_size"
+external abi_align : DataLayout.t -> Llvm.lltype -> int = "llvm_abi_align"
+external stack_align : DataLayout.t -> Llvm.lltype -> int = "llvm_stack_align"
+external preferred_align : DataLayout.t -> Llvm.lltype -> int
= "llvm_preferred_align"
-external preferred_align_of_global : TargetData.t -> Llvm.llvalue -> int
+external preferred_align_of_global : DataLayout.t -> Llvm.llvalue -> int
= "llvm_preferred_align_of_global"
-external element_at_offset : TargetData.t -> Llvm.lltype -> Int64.t -> int
+external element_at_offset : DataLayout.t -> Llvm.lltype -> Int64.t -> int
= "llvm_element_at_offset"
-external offset_of_element : TargetData.t -> Llvm.lltype -> int -> Int64.t
+external offset_of_element : DataLayout.t -> Llvm.lltype -> int -> Int64.t
= "llvm_offset_of_element"
diff --git a/bindings/ocaml/target/llvm_target.mli b/bindings/ocaml/target/llvm_target.mli
index c288b9ac2d..ab9c5e49ea 100644
--- a/bindings/ocaml/target/llvm_target.mli
+++ b/bindings/ocaml/target/llvm_target.mli
@@ -18,11 +18,11 @@ module Endian : sig
| Little
end
-module TargetData : sig
+module DataLayout : sig
type t
- (** [TargetData.create rep] parses the target data string representation [rep].
- See the constructor llvm::TargetData::TargetData. *)
+ (** [DataLayout.create rep] parses the target data string representation [rep].
+ See the constructor llvm::DataLayout::DataLayout. *)
external create : string -> t = "llvm_targetdata_create"
(** [add_target_data td pm] adds the target data [td] to the pass manager [pm].
@@ -32,64 +32,64 @@ module TargetData : sig
= "llvm_targetdata_add"
(** [as_string td] is the string representation of the target data [td].
- See the constructor llvm::TargetData::TargetData. *)
+ See the constructor llvm::DataLayout::DataLayout. *)
external as_string : t -> string = "llvm_targetdata_as_string"
- (** Deallocates a TargetData.
- See the destructor llvm::TargetData::~TargetData. *)
+ (** Deallocates a DataLayout.
+ See the destructor llvm::DataLayout::~DataLayout. *)
external dispose : t -> unit = "llvm_targetdata_dispose"
end
(** Returns the byte order of a target, either LLVMBigEndian or
LLVMLittleEndian.
- See the method llvm::TargetData::isLittleEndian. *)
-external byte_order : TargetData.t -> Endian.t = "llvm_byte_order"
+ See the method llvm::DataLayout::isLittleEndian. *)
+external byte_order : DataLayout.t -> Endian.t = "llvm_byte_order"
(** Returns the pointer size in bytes for a target.
- See the method llvm::TargetData::getPointerSize. *)
-external pointer_size : TargetData.t -> int = "llvm_pointer_size"
+ See the method llvm::DataLayout::getPointerSize. *)
+external pointer_size : DataLayout.t -> int = "llvm_pointer_size"
(** Returns the integer type that is the same size as a pointer on a target.
- See the method llvm::TargetData::getIntPtrType. *)
-external intptr_type : TargetData.t -> Llvm.lltype = "LLVMIntPtrType"
+ See the method llvm::DataLayout::getIntPtrType. *)
+external intptr_type : DataLayout.t -> Llvm.lltype = "LLVMIntPtrType"
(** Computes the size of a type in bytes for a target.
- See the method llvm::TargetData::getTypeSizeInBits. *)
-external size_in_bits : TargetData.t -> Llvm.lltype -> Int64.t
+ See the method llvm::DataLayout::getTypeSizeInBits. *)
+external size_in_bits : DataLayout.t -> Llvm.lltype -> Int64.t
= "llvm_size_in_bits"
(** Computes the storage size of a type in bytes for a target.
- See the method llvm::TargetData::getTypeStoreSize. *)
-external store_size : TargetData.t -> Llvm.lltype -> Int64.t = "llvm_store_size"
+ See the method llvm::DataLayout::getTypeStoreSize. *)
+external store_size : DataLayout.t -> Llvm.lltype -> Int64.t = "llvm_store_size"
(** Computes the ABI size of a type in bytes for a target.
- See the method llvm::TargetData::getTypeAllocSize. *)
-external abi_size : TargetData.t -> Llvm.lltype -> Int64.t = "llvm_abi_size"
+ See the method llvm::DataLayout::getTypeAllocSize. *)
+external abi_size : DataLayout.t -> Llvm.lltype -> Int64.t = "llvm_abi_size"
(** Computes the ABI alignment of a type in bytes for a target.
- See the method llvm::TargetData::getTypeABISize. *)
-external abi_align : TargetData.t -> Llvm.lltype -> int = "llvm_abi_align"
+ See the method llvm::DataLayout::getTypeABISize. *)
+external abi_align : DataLayout.t -> Llvm.lltype -> int = "llvm_abi_align"
(** Computes the call frame alignment of a type in bytes for a target.
- See the method llvm::TargetData::getTypeABISize. *)
-external stack_align : TargetData.t -> Llvm.lltype -> int = "llvm_stack_align"
+ See the method llvm::DataLayout::getTypeABISize. *)
+external stack_align : DataLayout.t -> Llvm.lltype -> int = "llvm_stack_align"
(** Computes the preferred alignment of a type in bytes for a target.
- See the method llvm::TargetData::getTypeABISize. *)
-external preferred_align : TargetData.t -> Llvm.lltype -> int
+ See the method llvm::DataLayout::getTypeABISize. *)
+external preferred_align : DataLayout.t -> Llvm.lltype -> int
= "llvm_preferred_align"
(** Computes the preferred alignment of a global variable in bytes for a target.
- See the method llvm::TargetData::getPreferredAlignment. *)
-external preferred_align_of_global : TargetData.t -> Llvm.llvalue -> int
+ See the method llvm::DataLayout::getPreferredAlignment. *)
+external preferred_align_of_global : DataLayout.t -> Llvm.llvalue -> int
= "llvm_preferred_align_of_global"
(** Computes the structure element that contains the byte offset for a target.
See the method llvm::StructLayout::getElementContainingOffset. *)
-external element_at_offset : TargetData.t -> Llvm.lltype -> Int64.t -> int
+external element_at_offset : DataLayout.t -> Llvm.lltype -> Int64.t -> int
= "llvm_element_at_offset"
(** Computes the byte offset of the indexed struct element for a target.
See the method llvm::StructLayout::getElementContainingOffset. *)
-external offset_of_element : TargetData.t -> Llvm.lltype -> int -> Int64.t
+external offset_of_element : DataLayout.t -> Llvm.lltype -> int -> Int64.t
= "llvm_offset_of_element"
diff --git a/bindings/ocaml/target/target_ocaml.c b/bindings/ocaml/target/target_ocaml.c
index ca01e7786b..62fe789a52 100644
--- a/bindings/ocaml/target/target_ocaml.c
+++ b/bindings/ocaml/target/target_ocaml.c
@@ -18,18 +18,18 @@
#include "llvm-c/Target.h"
#include "caml/alloc.h"
-/* string -> TargetData.t */
+/* string -> DataLayout.t */
CAMLprim LLVMTargetDataRef llvm_targetdata_create(value StringRep) {
return LLVMCreateTargetData(String_val(StringRep));
}
-/* TargetData.t -> [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
+/* DataLayout.t -> [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
CAMLprim value llvm_targetdata_add(LLVMTargetDataRef TD, LLVMPassManagerRef PM){
LLVMAddTargetData(TD, PM);
return Val_unit;
}
-/* TargetData.t -> string */
+/* DataLayout.t -> string */
CAMLprim value llvm_targetdata_as_string(LLVMTargetDataRef TD) {
char *StringRep = LLVMCopyStringRepOfTargetData(TD);
value Copy = copy_string(StringRep);
@@ -37,65 +37,65 @@ CAMLprim value llvm_targetdata_as_string(LLVMTargetDataRef TD) {
return Copy;
}
-/* TargetData.t -> unit */
+/* DataLayout.t -> unit */
CAMLprim value llvm_targetdata_dispose(LLVMTargetDataRef TD) {
LLVMDisposeTargetData(TD);
return Val_unit;
}
-/* TargetData.t -> Endian.t */
+/* DataLayout.t -> Endian.t */
CAMLprim value llvm_byte_order(LLVMTargetDataRef TD) {
return Val_int(LLVMByteOrder(TD));
}
-/* TargetData.t -> int */
+/* DataLayout.t -> int */
CAMLprim value llvm_pointer_size(LLVMTargetDataRef TD) {
return Val_int(LLVMPointerSize(TD));
}
-/* TargetData.t -> Llvm.lltype -> Int64.t */
+/* DataLayout.t -> Llvm.lltype -> Int64.t */
CAMLprim value llvm_size_in_bits(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
return caml_copy_int64(LLVMSizeOfTypeInBits(TD, Ty));
}
-/* TargetData.t -> Llvm.lltype -> Int64.t */
+/* DataLayout.t -> Llvm.lltype -> Int64.t */
CAMLprim value llvm_store_size(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
return caml_copy_int64(LLVMStoreSizeOfType(TD, Ty));
}
-/* TargetData.t -> Llvm.lltype -> Int64.t */
+/* DataLayout.t -> Llvm.lltype -> Int64.t */
CAMLprim value llvm_abi_size(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
return caml_copy_int64(LLVMABISizeOfType(TD, Ty));
}
-/* TargetData.t -> Llvm.lltype -> int */
+/* DataLayout.t -> Llvm.lltype -> int */
CAMLprim value llvm_abi_align(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
return Val_int(LLVMABIAlignmentOfType(TD, Ty));
}
-/* TargetData.t -> Llvm.lltype -> int */
+/* DataLayout.t -> Llvm.lltype -> int */
CAMLprim value llvm_stack_align(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
return Val_int(LLVMCallFrameAlignmentOfType(TD, Ty));
}
-/* TargetData.t -> Llvm.lltype -> int */
+/* DataLayout.t -> Llvm.lltype -> int */
CAMLprim value llvm_preferred_align(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
return Val_int(LLVMPreferredAlignmentOfType(TD, Ty));
}
-/* TargetData.t -> Llvm.llvalue -> int */
+/* DataLayout.t -> Llvm.llvalue -> int */
CAMLprim value llvm_preferred_align_of_global(LLVMTargetDataRef TD,
LLVMValueRef GlobalVar) {
return Val_int(LLVMPreferredAlignmentOfGlobal(TD, GlobalVar));
}
-/* TargetData.t -> Llvm.lltype -> Int64.t -> int */
+/* DataLayout.t -> Llvm.lltype -> Int64.t -> int */
CAMLprim value llvm_element_at_offset(LLVMTargetDataRef TD, LLVMTypeRef Ty,
value Offset) {
return Val_int(LLVMElementAtOffset(TD, Ty, Int_val(Offset)));
}
-/* TargetData.t -> Llvm.lltype -> int -> Int64.t */
+/* DataLayout.t -> Llvm.lltype -> int -> Int64.t */
CAMLprim value llvm_offset_of_element(LLVMTargetDataRef TD, LLVMTypeRef Ty,
value Index) {
return caml_copy_int64(LLVMOffsetOfElement(TD, Ty, Int_val(Index)));
diff --git a/cmake/modules/AddLLVM.cmake b/cmake/modules/AddLLVM.cmake
index f44a27cce8..a999f307d5 100755
--- a/cmake/modules/AddLLVM.cmake
+++ b/cmake/modules/AddLLVM.cmake
@@ -135,16 +135,22 @@ endmacro(add_llvm_target)
# lld, and Polly. This adds two options. One for the source directory of the
# project, which defaults to ${CMAKE_CURRENT_SOURCE_DIR}/${name}. Another to
# enable or disable building it with everthing else.
+# Additional parameter can be specified as the name of directory.
macro(add_llvm_external_project name)
- string(TOUPPER ${name} nameUPPER)
- set(LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${name}"
+ set(add_llvm_external_dir "${ARGN}")
+ if("${add_llvm_external_dir}" STREQUAL "")
+ set(add_llvm_external_dir ${name})
+ endif()
+ string(REPLACE "-" "_" nameUNDERSCORE ${name})
+ string(TOUPPER ${nameUNDERSCORE} nameUPPER)
+ set(LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir}"
CACHE PATH "Path to ${name} source directory")
if (NOT ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR} STREQUAL ""
AND EXISTS ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}/CMakeLists.txt)
option(LLVM_EXTERNAL_${nameUPPER}_BUILD
"Whether to build ${name} as part of LLVM" ON)
if (LLVM_EXTERNAL_${nameUPPER}_BUILD)
- add_subdirectory(${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR} ${name})
+ add_subdirectory(${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR} ${add_llvm_external_dir})
endif()
endif()
endmacro(add_llvm_external_project)
diff --git a/configure b/configure
index 70c4a6a65a..a12f00b1ff 100755
--- a/configure
+++ b/configure
@@ -790,6 +790,7 @@ OCAML_LIBDIR
ENABLE_VISIBILITY_INLINES_HIDDEN
RPATH
RDYNAMIC
+program_prefix
LIBOBJS
LTLIBOBJS'
ac_subst_files=''
@@ -10317,7 +10318,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 10315 "configure"
+#line 10316 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -21132,6 +21133,10 @@ fi
ac_config_files="$ac_config_files bindings/ocaml/llvm/META.llvm"
+test "x$program_prefix" = "xNONE" && program_prefix=""
+
+
+
ac_config_commands="$ac_config_commands setup"
ac_config_commands="$ac_config_commands Makefile"
@@ -22055,11 +22060,12 @@ OCAML_LIBDIR!$OCAML_LIBDIR$ac_delim
ENABLE_VISIBILITY_INLINES_HIDDEN!$ENABLE_VISIBILITY_INLINES_HIDDEN$ac_delim
RPATH!$RPATH$ac_delim
RDYNAMIC!$RDYNAMIC$ac_delim
+program_prefix!$program_prefix$ac_delim
LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 93; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 94; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/docs/AliasAnalysis.rst b/docs/AliasAnalysis.rst
index 2d4f2914ee..fdaec89cdf 100644
--- a/docs/AliasAnalysis.rst
+++ b/docs/AliasAnalysis.rst
@@ -230,7 +230,7 @@ any pass dependencies your pass has. Thus you should have something like this:
.. code-block:: c++
- void getAnalysisUsage(AnalysisUsage &amp;AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const {
AliasAnalysis::getAnalysisUsage(AU);
// declare your dependencies here.
}
diff --git a/docs/CodeGenerator.rst b/docs/CodeGenerator.rst
index d1d0231105..f387e7f4c5 100644
--- a/docs/CodeGenerator.rst
+++ b/docs/CodeGenerator.rst
@@ -81,7 +81,7 @@ Required components in the code generator
The two pieces of the LLVM code generator are the high-level interface to the
code generator and the set of reusable components that can be used to build
target-specific backends. The two most important interfaces (:raw-html:`<tt>`
-`TargetMachine`_ :raw-html:`</tt>` and :raw-html:`<tt>` `TargetData`_
+`TargetMachine`_ :raw-html:`</tt>` and :raw-html:`<tt>` `DataLayout`_
:raw-html:`</tt>`) are the only ones that are required to be defined for a
backend to fit into the LLVM system, but the others must be defined if the
reusable code generator components are going to be used.
@@ -197,7 +197,7 @@ any particular client. These classes are designed to capture the *abstract*
properties of the target (such as the instructions and registers it has), and do
not incorporate any particular pieces of code generation algorithms.
-All of the target description classes (except the :raw-html:`<tt>` `TargetData`_
+All of the target description classes (except the :raw-html:`<tt>` `DataLayout`_
:raw-html:`</tt>` class) are designed to be subclassed by the concrete target
implementation, and have virtual methods implemented. To get to these
implementations, the :raw-html:`<tt>` `TargetMachine`_ :raw-html:`</tt>` class
@@ -214,18 +214,18 @@ the ``get*Info`` methods (``getInstrInfo``, ``getRegisterInfo``,
``getFrameInfo``, etc.). This class is designed to be specialized by a concrete
target implementation (e.g., ``X86TargetMachine``) which implements the various
virtual methods. The only required target description class is the
-:raw-html:`<tt>` `TargetData`_ :raw-html:`</tt>` class, but if the code
+:raw-html:`<tt>` `DataLayout`_ :raw-html:`</tt>` class, but if the code
generator components are to be used, the other interfaces should be implemented
as well.
-.. _TargetData:
+.. _DataLayout:
-The ``TargetData`` class
+The ``DataLayout`` class
------------------------
-The ``TargetData`` class is the only required target description class, and it
+The ``DataLayout`` class is the only required target description class, and it
is the only class that is not extensible (you cannot derived a new class from
-it). ``TargetData`` specifies information about how the target lays out memory
+it). ``DataLayout`` specifies information about how the target lays out memory
for structures, the alignment requirements for various data types, the size of
pointers in the target, and whether the target is little-endian or
big-endian.
@@ -390,7 +390,7 @@ functions make it easy to build arbitrary machine instructions. Usage of the
MachineInstr *MI = BuildMI(X86::MOV32ri, 1, DestReg).addImm(42);
// Create the same instr, but insert it at the end of a basic block.
- MachineBasicBlock &amp;MBB = ...
+ MachineBasicBlock &MBB = ...
BuildMI(MBB, X86::MOV32ri, 1, DestReg).addImm(42);
// Create the same instr, but insert it before a specified iterator point.
@@ -404,7 +404,7 @@ functions make it easy to build arbitrary machine instructions. Usage of the
MI = BuildMI(X86::SAHF, 0);
// Create a self looping branch instruction.
- BuildMI(MBB, X86::JNE, 1).addMBB(&amp;MBB);
+ BuildMI(MBB, X86::JNE, 1).addMBB(&MBB);
The key thing to remember with the ``BuildMI`` functions is that you have to
specify the number of operands that the machine instruction will take. This
diff --git a/docs/CodingStandards.rst b/docs/CodingStandards.rst
index 455ffd5292..de50e6eeaf 100644
--- a/docs/CodingStandards.rst
+++ b/docs/CodingStandards.rst
@@ -79,10 +79,11 @@ tree. The standard header looks like this:
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
- //
- // This file contains the declaration of the Instruction class, which is the
- // base class for all of the VM instructions.
- //
+ ///
+ /// \file
+ /// \brief This file contains the declaration of the Instruction class, which is
+ /// the base class for all of the VM instructions.
+ ///
//===----------------------------------------------------------------------===//
A few things to note about this particular format: The "``-*- C++ -*-``" string
@@ -100,10 +101,12 @@ The next section in the file is a concise note that defines the license that the
file is released under. This makes it perfectly clear what terms the source
code can be distributed under and should not be modified in any way.
-The main body of the description does not have to be very long in most cases.
-Here it's only two lines. If an algorithm is being implemented or something
-tricky is going on, a reference to the paper where it is published should be
-included, as well as any notes or *gotchas* in the code to watch out for.
+The main body is a ``doxygen`` comment describing the purpose of the file. It
+should have a ``\brief`` command that describes the file in one or two
+sentences. Any additional information should be separated by a blank line. If
+an algorithm is being implemented or something tricky is going on, a reference
+to the paper where it is published should be included, as well as any notes or
+*gotchas* in the code to watch out for.
Class overviews
"""""""""""""""
@@ -714,7 +717,7 @@ enforced, and hopefully what to do about it. Here is one complete example:
.. code-block:: c++
inline Value *getOperand(unsigned i) {
- assert(i < Operands.size() &amp;&amp; "getOperand() out of range!");
+ assert(i < Operands.size() && "getOperand() out of range!");
return Operands[i];
}
diff --git a/docs/CompilerWriterInfo.html b/docs/CompilerWriterInfo.html
deleted file mode 100644
index 66190655fa..0000000000
--- a/docs/CompilerWriterInfo.html
+++ /dev/null
@@ -1,267 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
- "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <title>Architecture/platform information for compiler writers</title>
- <link rel="stylesheet" href="_static/llvm.css" type="text/css">
-</head>
-
-<body>
-
-<h1>
- Architecture/platform information for compiler writers
-</h1>
-
-<div class="doc_warning">
- <p>Note: This document is a work-in-progress. Additions and clarifications
- are welcome.</p>
-</div>
-
-<ol>
- <li><a href="#hw">Hardware</a>
- <ol>
- <li><a href="#arm">ARM</a></li>
- <li><a href="#ia64">Itanium</a></li>
- <li><a href="#mips">MIPS</a></li>
- <li><a href="#ppc">PowerPC</a></li>
- <li><a href="#sparc">SPARC</a></li>
- <li><a href="#x86">X86</a></li>
- <li><a href="#other">Other lists</a></li>
- </ol></li>
- <li><a href="#abi">Application Binary Interface (ABI)</a>
- <ol>
- <li><a href="#linux">Linux</a></li>
- <li><a href="#osx">OS X</a></li>
- </ol></li>
- <li><a href="#misc">Miscellaneous resources</a></li>
-</ol>
-
-<div class="doc_author">
- <p>Compiled by <a href="http://misha.brukman.net">Misha Brukman</a></p>
-</div>
-
-<!-- *********************************************************************** -->
-<h2><a name="hw">Hardware</a></h2>
-<!-- *********************************************************************** -->
-
-<div>
-
-<!-- ======================================================================= -->
-<h3><a name="arm">ARM</a></h3>
-
-<div>
-<ul>
-<li><a href="http://www.arm.com/documentation/">ARM documentation</a>
-(<a href="http://www.arm.com/documentation/ARMProcessor_Cores/">Processor
-Cores</a>)</li>
-<li><a href="http://www.arm.com/products/DevTools/ABI.html">ABI</a></li>
-</ul>
-</div>
-
-<!-- ======================================================================= -->
-<h3><a name="ia64">Itanium (ia64)</a></h3>
-
-<div>
-<ul>
-<li><a
-href="http://developer.intel.com/design/itanium2/documentation.htm">Itanium documentation</a>
-</li>
-</ul>
-</div>
-
-<!-- ======================================================================= -->
-<h3><a name="mips">MIPS</a></h3>
-
-<div>
-<ul>
-<li><a
-href="http://mips.com/content/Documentation/MIPSDocumentation/ProcessorArchitecture/doclibrary">MIPS
-Processor Architecture</a></li>
-</ul>
-</div>
-
-<!-- ======================================================================= -->
-<h3><a name="ppc">PowerPC</a></h3>
-
-<div>
-
-<!-- _______________________________________________________________________ -->
-<h4>IBM - Official manuals and docs</h4>
-
-<div>
-
-<ul>
-<li><a
-href="http://www-106.ibm.com/developerworks/eserver/articles/archguide.html">PowerPC
-Architecture Book</a>
-<ul>
- <li>Book I: <a
- href="http://www-106.ibm.com/developerworks/eserver/pdfs/archpub1.pdf">PowerPC
- User Instruction Set Architecture</a></li>
- <li>Book II: <a
- href="http://www-106.ibm.com/developerworks/eserver/pdfs/archpub2.pdf">PowerPC
- Virtual Environment Architecture</a></li>
- <li>Book III: <a
- href="http://www-106.ibm.com/developerworks/eserver/pdfs/archpub3.pdf">PowerPC
- Operating Environment Architecture</a></li>
-</ul></li>
-<li><a
-href="http://www-3.ibm.com/chips/techlib/techlib.nsf/techdocs/852569B20050FF7785256996007558C6">PowerPC
-Compiler Writer's Guide</a></li>
-<li><A
-href="http://www-3.ibm.com/chips/techlib/techlib.nsf/products/PowerPC">PowerPC
-Processor Manuals</a></li>
-<li><a
-href="http://www-106.ibm.com/developerworks/linux/library/l-powarch/">Intro to
-PowerPC architecture</a></li>
-<li><a href="http://publibn.boulder.ibm.com/doc_link/en_US/a_doc_lib/aixassem/alangref/alangreftfrm.htm">IBM AIX/5L for POWER Assembly reference</a></li>
-</ul>
-
-</div>
-
-<!-- _______________________________________________________________________ -->
-<h4>Other documents, collections, notes</h4>
-
-<div>
-
-<ul>
-<li><a href="http://penguinppc.org/dev/#library">PowerPC ABI documents</a></li>
-<li><a href="http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00997.html">PowerPC64
-alignment of long doubles (from GCC)</a></li>
-<li><a href="http://sources.redhat.com/ml/binutils/2002-04/msg00573.html">Long
-branch stubs for powerpc64-linux (from binutils)</a></li>
-</ul>
-
-</div>
-
-</div>
-
-<!-- ======================================================================= -->
-<h3><a name="sparc">SPARC</a></h3>
-
-<div>
-
-<ul>
-<li><a href="http://www.sparc.org/resource.htm">SPARC resources</a></li>
-<li><a href="http://www.sparc.org/standards.html">SPARC standards</a></li>
-</ul>
-
-</div>
-
-<!-- ======================================================================= -->
-<h3><a name="x86">X86</a></h3>
-
-<div>
-
-<!-- _______________________________________________________________________ -->
-<h4>AMD - Official manuals and docs</h4>
-
-<div>
-<ul>
-<li><a
-href="http://www.amd.com/us-en/Processors/TechnicalResources/0,,30_182_739,00.html">AMD processor manuals</a></li>
-<li><a href="http://www.x86-64.org/documentation">X86-64 ABI</a></li>
-</ul>
-</div>
-
-<!-- _______________________________________________________________________ -->
-<h4>Intel - Official manuals and docs</h4>
-
-<div>
-<ul>
-<li><a
-href="http://developer.intel.com/design/pentium4/manuals/index_new.htm">IA-32
-manuals</a></li>
-<li><a
-href="http://www.intel.com/design/itanium/documentation.htm?iid=ipp_srvr_proc_itanium2+techdocs">Intel
-Itanium documentation</a></li>
-</ul>
-</div>
-
-<!-- _______________________________________________________________________ -->
-<h4>Other x86-specific information</h4>
-
-<div>
-<ul>
-<li><a href="http://www.agner.org/assem/calling_conventions.pdf">Calling
-conventions for different C++ compilers and operating systems</a></li>
-</ul>
-</div>
-
-</div>
-
-<!-- ======================================================================= -->
-<h3><a name="other">Other relevant lists</a></h3>
-
-<div>
-
-<ul>
-<li><a href="http://gcc.gnu.org/readings.html">GCC reading list</a></li>
-</ul>
-
-</div>
-
-</div>
-
-<!-- *********************************************************************** -->
-<h2><a name="abi">ABI</a></h2>
-<!-- *********************************************************************** -->
-
-<div>
-
-<!-- ======================================================================= -->
-<h3><a name="linux">Linux</a></h3>
-
-<div>
-<ol>
-<li><a href="http://www.linuxbase.org/spec/ELF/ppc64/">PowerPC 64-bit ELF ABI
-Supplement</a></li>
-</ol>
-</div>
-
-<!-- ======================================================================= -->
-<h3><a name="osx">OS X</a></h3>
-
-<div>
-<ol>
-<li><a
-href="http://developer.apple.com/documentation/Darwin/RuntimeArchitecture-date.html">Mach-O
-Runtime Architecture</a></li>
-<li><a href="http://www.unsanity.org/archives/000044.php">Notes on Mach-O
-ABI</a></li>
-</ol>
-
-</div>
-
-</div>
-
-<!-- *********************************************************************** -->
-<h2><a name="misc">Miscellaneous resources</a></h2>
-<!-- *********************************************************************** -->
-
-<ul>
-<li><a
-href="http://www.nondot.org/sabre/os/articles/ExecutableFileFormats/">Executable
-File Format library</a></li>
-<li><a href="http://gcc.gnu.org/projects/prefetch.html">GCC prefetch project</a>
-page has a good survey of the prefetching capabilities of a variety of modern
-processors.</li>
-</ul>
-
-<!-- *********************************************************************** -->
-
-<hr>
-<address>
- <a href="http://jigsaw.w3.org/css-validator/check/referer"><img
- src="http://jigsaw.w3.org/css-validator/images/vcss-blue" alt="Valid CSS"></a>
- <a href="http://validator.w3.org/check/referer"><img
- src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
-
- <a href="http://misha.brukman.net">Misha Brukman</a><br>
- <a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
- Last modified: $Date$
-</address>
-
-</body>
-</html>
diff --git a/docs/CompilerWriterInfo.rst b/docs/CompilerWriterInfo.rst
new file mode 100644
index 0000000000..e41f5f9eec
--- /dev/null
+++ b/docs/CompilerWriterInfo.rst
@@ -0,0 +1,118 @@
+.. _compiler_writer_info:
+
+========================================================
+Architecture & Platform Information for Compiler Writers
+========================================================
+
+.. contents::
+ :local:
+
+.. note::
+
+ This document is a work-in-progress. Additions and clarifications are
+ welcome.
+
+ Compiled by `Misha Brukman <http://misha.brukman.net>`_.
+
+Hardware
+========
+
+ARM
+---
+
+* `ARM documentation <http://www.arm.com/documentation/>`_ (`Processor Cores <http://www.arm.com/documentation/ARMProcessor_Cores/>`_ Cores)
+
+* `ABI <http://www.arm.com/products/DevTools/ABI.html>`_
+
+Itanium (ia64)
+--------------
+
+* `Itanium documentation <http://developer.intel.com/design/itanium2/documentation.htm>`_
+
+MIPS
+----
+
+* `MIPS Processor Architecture <http://mips.com/content/Documentation/MIPSDocumentation/ProcessorArchitecture/doclibrary>`_
+
+PowerPC
+-------
+
+IBM - Official manuals and docs
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* `PowerPC Architecture Book <http://www-106.ibm.com/developerworks/eserver/articles/archguide.html>`_
+
+ * Book I: `PowerPC User Instruction Set Architecture <http://www-106.ibm.com/developerworks/eserver/pdfs/archpub1.pdf>`_
+
+ * Book II: `PowerPC Virtual Environment Architecture <http://www-106.ibm.com/developerworks/eserver/pdfs/archpub2.pdf>`_
+
+ * Book III: `PowerPC Operating Environment Architecture <http://www-106.ibm.com/developerworks/eserver/pdfs/archpub3.pdf>`_
+
+* `PowerPC Compiler Writer's Guide <http://www-3.ibm.com/chips/techlib/techlib.nsf/techdocs/852569B20050FF7785256996007558C6>`_
+
+* `PowerPC Processor Manuals <http://www-3.ibm.com/chips/techlib/techlib.nsf/products/PowerPC>`_
+
+* `Intro to PowerPC Architecture <http://www-106.ibm.com/developerworks/linux/library/l-powarch/>`_
+
+* `IBM AIX/5L for POWER Assembly Reference <http://publibn.boulder.ibm.com/doc_link/en_US/a_doc_lib/aixassem/alangref/alangreftfrm.htm>`_
+
+Other documents, collections, notes
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* `PowerPC ABI documents <http://penguinppc.org/dev/#library>`_
+* `PowerPC64 alignment of long doubles (from GCC) <http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00997.html>`_
+* `Long branch stubs for powerpc64-linux (from binutils) <http://sources.redhat.com/ml/binutils/2002-04/msg00573.html>`_
+
+SPARC
+-----
+
+* `SPARC resources <http://www.sparc.org/resource.htm>`_
+* `SPARC standards <http://www.sparc.org/standards.html>`_
+
+X86
+---
+
+AMD - Official manuals and docs
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* `AMD processor manuals <http://www.amd.com/us-en/Processors/TechnicalResources/0,,30_182_739,00.html>`_
+* `X86-64 ABI <http://www.x86-64.org/documentation>`_
+
+Intel - Official manuals and docs
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* `IA-32 manuals <http://developer.intel.com/design/pentium4/manuals/index_new.htm>`_
+* `Intel Itanium documentation <http://www.intel.com/design/itanium/documentation.htm?iid=ipp_srvr_proc_itanium2+techdocs>`_
+
+Other x86-specific information
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* `Calling conventions for different C++ compilers and operating systems <http://www.agner.org/assem/calling_conventions.pdf>`_
+
+Other relevant lists
+--------------------
+
+* `GCC reading list <http://gcc.gnu.org/readings.html>`_
+
+ABI
+===
+
+Linux
+-----
+
+* `PowerPC 64-bit ELF ABI Supplement <http://www.linuxbase.org/spec/ELF/ppc64/>`_
+
+OS X
+----
+
+* `Mach-O Runtime Architecture <http://developer.apple.com/documentation/Darwin/RuntimeArchitecture-date.html>`_
+* `Notes on Mach-O ABI <http://www.unsanity.org/archives/000044.php>`_
+
+Miscellaneous Resources
+=======================
+
+* `Executable File Format library <http://www.nondot.org/sabre/os/articles/ExecutableFileFormats/>`_
+
+* `GCC prefetch project <http://gcc.gnu.org/projects/prefetch.html>`_ page has a
+ good survey of the prefetching capabilities of a variety of modern
+ processors.
diff --git a/docs/ExtendingLLVM.html b/docs/ExtendingLLVM.html
deleted file mode 100644
index 99e209b894..0000000000
--- a/docs/ExtendingLLVM.html
+++ /dev/null
@@ -1,379 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
- "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <title>Extending LLVM: Adding instructions, intrinsics, types, etc.</title>
- <link rel="stylesheet" href="_static/llvm.css" type="text/css">
-</head>
-
-<body>
-
-<h1>
- Extending LLVM: Adding instructions, intrinsics, types, etc.
-</h1>
-
-<ol>
- <li><a href="#introduction">Introduction and Warning</a></li>
- <li><a href="#intrinsic">Adding a new intrinsic function</a></li>
- <li><a href="#instruction">Adding a new instruction</a></li>
- <li><a href="#sdnode">Adding a new SelectionDAG node</a></li>
- <li><a href="#type">Adding a new type</a>
- <ol>
- <li><a href="#fund_type">Adding a new fundamental type</a></li>
- <li><a href="#derived_type">Adding a new derived type</a></li>
- </ol></li>
-</ol>
-
-<div class="doc_author">
- <p>Written by <a href="http://misha.brukman.net">Misha Brukman</a>,
- Brad Jones, Nate Begeman,
- and <a href="http://nondot.org/sabre">Chris Lattner</a></p>
-</div>
-
-<!-- *********************************************************************** -->
-<h2>
- <a name="introduction">Introduction and Warning</a>
-</h2>
-<!-- *********************************************************************** -->
-
-<div>
-
-<p>During the course of using LLVM, you may wish to customize it for your
-research project or for experimentation. At this point, you may realize that
-you need to add something to LLVM, whether it be a new fundamental type, a new
-intrinsic function, or a whole new instruction.</p>
-
-<p>When you come to this realization, stop and think. Do you really need to
-extend LLVM? Is it a new fundamental capability that LLVM does not support at
-its current incarnation or can it be synthesized from already pre-existing LLVM
-elements? If you are not sure, ask on the <a
-href="http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev">LLVM-dev</a> list. The
-reason is that extending LLVM will get involved as you need to update all the
-different passes that you intend to use with your extension, and there are
-<em>many</em> LLVM analyses and transformations, so it may be quite a bit of
-work.</p>
-
-<p>Adding an <a href="#intrinsic">intrinsic function</a> is far easier than
-adding an instruction, and is transparent to optimization passes. If your added
-functionality can be expressed as a
-function call, an intrinsic function is the method of choice for LLVM
-extension.</p>
-
-<p>Before you invest a significant amount of effort into a non-trivial
-extension, <span class="doc_warning">ask on the list</span> if what you are
-looking to do can be done with already-existing infrastructure, or if maybe
-someone else is already working on it. You will save yourself a lot of time and
-effort by doing so.</p>
-
-</div>
-
-<!-- *********************************************************************** -->
-<h2>
- <a name="intrinsic">Adding a new intrinsic function</a>
-</h2>
-<!-- *********************************************************************** -->
-
-<div>
-
-<p>Adding a new intrinsic function to LLVM is much easier than adding a new
-instruction. Almost all extensions to LLVM should start as an intrinsic
-function and then be turned into an instruction if warranted.</p>
-
-<ol>
-<li><tt>llvm/docs/LangRef.html</tt>:
- Document the intrinsic. Decide whether it is code generator specific and
- what the restrictions are. Talk to other people about it so that you are
- sure it's a good idea.</li>
-
-<li><tt>llvm/include/llvm/Intrinsics*.td</tt>:
- Add an entry for your intrinsic. Describe its memory access characteristics
- for optimization (this controls whether it will be DCE'd, CSE'd, etc). Note
- that any intrinsic using the <tt>llvm_int_ty</tt> type for an argument will
- be deemed by <tt>tblgen</tt> as overloaded and the corresponding suffix
- will be required on the intrinsic's name.</li>
-
-<li><tt>llvm/lib/Analysis/ConstantFolding.cpp</tt>: If it is possible to
- constant fold your intrinsic, add support to it in the
- <tt>canConstantFoldCallTo</tt> and <tt>ConstantFoldCall</tt> functions.</li>
-
-<li><tt>llvm/test/Regression/*</tt>: Add test cases for your test cases to the
- test suite</li>
-</ol>
-
-<p>Once the intrinsic has been added to the system, you must add code generator
-support for it. Generally you must do the following steps:</p>
-
-<dl>
-
-<dt>Add support to the .td file for the target(s) of your choice in
- <tt>lib/Target/*/*.td</tt>.</dt>
-
-<dd>This is usually a matter of adding a pattern to the .td file that matches
- the intrinsic, though it may obviously require adding the instructions you
- want to generate as well. There are lots of examples in the PowerPC and X86
- backend to follow.</dd>
-</dl>
-
-</div>
-
-<!-- *********************************************************************** -->
-<h2>
- <a name="sdnode">Adding a new SelectionDAG node</a>
-</h2>
-<!-- *********************************************************************** -->
-
-<div>
-
-<p>As with intrinsics, adding a new SelectionDAG node to LLVM is much easier
-than adding a new instruction. New nodes are often added to help represent
-instructions common to many targets. These nodes often map to an LLVM
-instruction (add, sub) or intrinsic (byteswap, population count). In other
-cases, new nodes have been added to allow many targets to perform a common task
-(converting between floating point and integer representation) or capture more
-complicated behavior in a single node (rotate).</p>
-
-<ol>
-<li><tt>include/llvm/CodeGen/ISDOpcodes.h</tt>:
- Add an enum value for the new SelectionDAG node.</li>
-<li><tt>lib/CodeGen/SelectionDAG/SelectionDAG.cpp</tt>:
- Add code to print the node to <tt>getOperationName</tt>. If your new node
- can be evaluated at compile time when given constant arguments (such as an
- add of a constant with another constant), find the <tt>getNode</tt> method
- that takes the appropriate number of arguments, and add a case for your node
- to the switch statement that performs constant folding for nodes that take
- the same number of arguments as your new node.</li>
-<li><tt>lib/CodeGen/SelectionDAG/LegalizeDAG.cpp</tt>:
- Add code to <a href="CodeGenerator.html#selectiondag_legalize">legalize,
- promote, and expand</a> the node as necessary. At a minimum, you will need
- to add a case statement for your node in <tt>LegalizeOp</tt> which calls
- LegalizeOp on the node's operands, and returns a new node if any of the
- operands changed as a result of being legalized. It is likely that not all
- targets supported by the SelectionDAG framework will natively support the
- new node. In this case, you must also add code in your node's case
- statement in <tt>LegalizeOp</tt> to Expand your node into simpler, legal
- operations. The case for <tt>ISD::UREM</tt> for expanding a remainder into
- a divide, multiply, and a subtract is a good example.</li>
-<li><tt>lib/CodeGen/SelectionDAG/LegalizeDAG.cpp</tt>:
- If targets may support the new node being added only at certain sizes, you
- will also need to add code to your node's case statement in
- <tt>LegalizeOp</tt> to Promote your node's operands to a larger size, and
- perform the correct operation. You will also need to add code to
- <tt>PromoteOp</tt> to do this as well. For a good example, see
- <tt>ISD::BSWAP</tt>,
- which promotes its operand to a wider size, performs the byteswap, and then
- shifts the correct bytes right to emulate the narrower byteswap in the
- wider type.</li>
-<li><tt>lib/CodeGen/SelectionDAG/LegalizeDAG.cpp</tt>:
- Add a case for your node in <tt>ExpandOp</tt> to teach the legalizer how to
- perform the action represented by the new node on a value that has been
- split into high and low halves. This case will be used to support your
- node with a 64 bit operand on a 32 bit target.</li>
-<li><tt>lib/CodeGen/SelectionDAG/DAGCombiner.cpp</tt>:
- If your node can be combined with itself, or other existing nodes in a
- peephole-like fashion, add a visit function for it, and call that function
- from <tt></tt>. There are several good examples for simple combines you
- can do; <tt>visitFABS</tt> and <tt>visitSRL</tt> are good starting places.
- </li>
-<li><tt>lib/Target/PowerPC/PPCISelLowering.cpp</tt>:
- Each target has an implementation of the <tt>TargetLowering</tt> class,
- usually in its own file (although some targets include it in the same
- file as the DAGToDAGISel). The default behavior for a target is to
- assume that your new node is legal for all types that are legal for
- that target. If this target does not natively support your node, then
- tell the target to either Promote it (if it is supported at a larger
- type) or Expand it. This will cause the code you wrote in
- <tt>LegalizeOp</tt> above to decompose your new node into other legal
- nodes for this target.</li>
-<li><tt>lib/Target/TargetSelectionDAG.td</tt>:
- Most current targets supported by LLVM generate code using the DAGToDAG
- method, where SelectionDAG nodes are pattern matched to target-specific
- nodes, which represent individual instructions. In order for the targets
- to match an instruction to your new node, you must add a def for that node
- to the list in this file, with the appropriate type constraints. Look at
- <tt>add</tt>, <tt>bswap</tt>, and <tt>fadd</tt> for examples.</li>
-<li><tt>lib/Target/PowerPC/PPCInstrInfo.td</tt>:
- Each target has a tablegen file that describes the target's instruction
- set. For targets that use the DAGToDAG instruction selection framework,
- add a pattern for your new node that uses one or more target nodes.
- Documentation for this is a bit sparse right now, but there are several
- decent examples. See the patterns for <tt>rotl</tt> in
- <tt>PPCInstrInfo.td</tt>.</li>
-<li>TODO: document complex patterns.</li>
-<li><tt>llvm/test/Regression/CodeGen/*</tt>: Add test cases for your new node
- to the test suite. <tt>llvm/test/Regression/CodeGen/X86/bswap.ll</tt> is
- a good example.</li>
-</ol>
-
-</div>
-
-<!-- *********************************************************************** -->
-<h2>
- <a name="instruction">Adding a new instruction</a>
-</h2>
-<!-- *********************************************************************** -->
-
-<div>
-
-<p><span class="doc_warning">WARNING: adding instructions changes the bitcode
-format, and it will take some effort to maintain compatibility with
-the previous version.</span> Only add an instruction if it is absolutely
-necessary.</p>
-
-<ol>
-
-<li><tt>llvm/include/llvm/Instruction.def</tt>:
- add a number for your instruction and an enum name</li>
-
-<li><tt>llvm/include/llvm/Instructions.h</tt>:
- add a definition for the class that will represent your instruction</li>
-
-<li><tt>llvm/include/llvm/Support/InstVisitor.h</tt>:
- add a prototype for a visitor to your new instruction type</li>
-
-<li><tt>llvm/lib/AsmParser/Lexer.l</tt>:
- add a new token to parse your instruction from assembly text file</li>
-
-<li><tt>llvm/lib/AsmParser/llvmAsmParser.y</tt>:
- add the grammar on how your instruction can be read and what it will
- construct as a result</li>
-
-<li><tt>llvm/lib/Bitcode/Reader/Reader.cpp</tt>:
- add a case for your instruction and how it will be parsed from bitcode</li>
-
-<li><tt>llvm/lib/VMCore/Instruction.cpp</tt>:
- add a case for how your instruction will be printed out to assembly</li>
-
-<li><tt>llvm/lib/VMCore/Instructions.cpp</tt>:
- implement the class you defined in
- <tt>llvm/include/llvm/Instructions.h</tt></li>
-
-<li>Test your instruction</li>
-
-<li><tt>llvm/lib/Target/*</tt>:
- Add support for your instruction to code generators, or add a lowering
- pass.</li>
-
-<li><tt>llvm/test/Regression/*</tt>: add your test cases to the test suite.</li>
-
-</ol>
-
-<p>Also, you need to implement (or modify) any analyses or passes that you want
-to understand this new instruction.</p>
-
-</div>
-
-
-<!-- *********************************************************************** -->
-<h2>
- <a name="type">Adding a new type</a>
-</h2>
-<!-- *********************************************************************** -->
-
-<div>
-
-<p><span class="doc_warning">WARNING: adding new types changes the bitcode
-format, and will break compatibility with currently-existing LLVM
-installations.</span> Only add new types if it is absolutely necessary.</p>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="fund_type">Adding a fundamental type</a>
-</h3>
-
-<div>
-
-<ol>
-
-<li><tt>llvm/include/llvm/Type.h</tt>:
- add enum for the new type; add static <tt>Type*</tt> for this type</li>
-
-<li><tt>llvm/lib/VMCore/Type.cpp</tt>:
- add mapping from <tt>TypeID</tt> =&gt; <tt>Type*</tt>;
- initialize the static <tt>Type*</tt></li>
-
-<li><tt>llvm/lib/AsmReader/Lexer.l</tt>:
- add ability to parse in the type from text assembly</li>
-
-<li><tt>llvm/lib/AsmReader/llvmAsmParser.y</tt>:
- add a token for that type</li>
-
-</ol>
-
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="derived_type">Adding a derived type</a>
-</h3>
-
-<div>
-
-<ol>
-<li><tt>llvm/include/llvm/Type.h</tt>:
- add enum for the new type; add a forward declaration of the type
- also</li>
-
-<li><tt>llvm/include/llvm/DerivedTypes.h</tt>:
- add new class to represent new class in the hierarchy; add forward
- declaration to the TypeMap value type</li>
-
-<li><tt>llvm/lib/VMCore/Type.cpp</tt>:
- add support for derived type to:
-<div class="doc_code">
-<pre>
-std::string getTypeDescription(const Type &amp;Ty,
- std::vector&lt;const Type*&gt; &amp;TypeStack)
-bool TypesEqual(const Type *Ty, const Type *Ty2,
- std::map&lt;const Type*, const Type*&gt; &amp; EqTypes)
-</pre>
-</div>
- add necessary member functions for type, and factory methods</li>
-
-<li><tt>llvm/lib/AsmReader/Lexer.l</tt>:
- add ability to parse in the type from text assembly</li>
-
-<li><tt>llvm/lib/BitCode/Writer/Writer.cpp</tt>:
- modify <tt>void BitcodeWriter::outputType(const Type *T)</tt> to serialize
- your type</li>
-
-<li><tt>llvm/lib/BitCode/Reader/Reader.cpp</tt>:
- modify <tt>const Type *BitcodeReader::ParseType()</tt> to read your data
- type</li>
-
-<li><tt>llvm/lib/VMCore/AsmWriter.cpp</tt>:
- modify
-<div class="doc_code">
-<pre>
-void calcTypeName(const Type *Ty,
- std::vector&lt;const Type*&gt; &amp;TypeStack,
- std::map&lt;const Type*,std::string&gt; &amp;TypeNames,
- std::string &amp; Result)
-</pre>
-</div>
- to output the new derived type
-</li>
-
-
-</ol>
-
-</div>
-
-</div>
-
-<!-- *********************************************************************** -->
-
-<hr>
-<address>
- <a href="http://jigsaw.w3.org/css-validator/check/referer"><img
- src="http://jigsaw.w3.org/css-validator/images/vcss-blue" alt="Valid CSS"></a>
- <a href="http://validator.w3.org/check/referer"><img
- src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
-
- <a href="http://llvm.org/">The LLVM Compiler Infrastructure</a>
- <br>
- Last modified: $Date$
-</address>
-
-</body>
-</html>
diff --git a/docs/ExtendingLLVM.rst b/docs/ExtendingLLVM.rst
new file mode 100644
index 0000000000..e41cfd996e
--- /dev/null
+++ b/docs/ExtendingLLVM.rst
@@ -0,0 +1,306 @@
+.. _extending_llvm:
+
+============================================================
+Extending LLVM: Adding instructions, intrinsics, types, etc.
+============================================================
+
+Introduction and Warning
+========================
+
+
+During the course of using LLVM, you may wish to customize it for your research
+project or for experimentation. At this point, you may realize that you need to
+add something to LLVM, whether it be a new fundamental type, a new intrinsic
+function, or a whole new instruction.
+
+When you come to this realization, stop and think. Do you really need to extend
+LLVM? Is it a new fundamental capability that LLVM does not support at its
+current incarnation or can it be synthesized from already pre-existing LLVM
+elements? If you are not sure, ask on the `LLVM-dev
+<http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev>`_ list. The reason is that
+extending LLVM will get involved as you need to update all the different passes
+that you intend to use with your extension, and there are ``many`` LLVM analyses
+and transformations, so it may be quite a bit of work.
+
+Adding an `intrinsic function`_ is far easier than adding an
+instruction, and is transparent to optimization passes. If your added
+functionality can be expressed as a function call, an intrinsic function is the
+method of choice for LLVM extension.
+
+Before you invest a significant amount of effort into a non-trivial extension,
+**ask on the list** if what you are looking to do can be done with
+already-existing infrastructure, or if maybe someone else is already working on
+it. You will save yourself a lot of time and effort by doing so.
+
+.. _intrinsic function:
+
+Adding a new intrinsic function
+===============================
+
+Adding a new intrinsic function to LLVM is much easier than adding a new
+instruction. Almost all extensions to LLVM should start as an intrinsic
+function and then be turned into an instruction if warranted.
+
+#. ``llvm/docs/LangRef.html``:
+
+ Document the intrinsic. Decide whether it is code generator specific and
+ what the restrictions are. Talk to other people about it so that you are
+ sure it's a good idea.
+
+#. ``llvm/include/llvm/Intrinsics*.td``:
+
+ Add an entry for your intrinsic. Describe its memory access characteristics
+ for optimization (this controls whether it will be DCE'd, CSE'd, etc). Note
+ that any intrinsic using the ``llvm_int_ty`` type for an argument will
+ be deemed by ``tblgen`` as overloaded and the corresponding suffix will
+ be required on the intrinsic's name.
+
+#. ``llvm/lib/Analysis/ConstantFolding.cpp``:
+
+ If it is possible to constant fold your intrinsic, add support to it in the
+ ``canConstantFoldCallTo`` and ``ConstantFoldCall`` functions.
+
+#. ``llvm/test/Regression/*``:
+
+ Add test cases for your test cases to the test suite
+
+Once the intrinsic has been added to the system, you must add code generator
+support for it. Generally you must do the following steps:
+
+Add support to the .td file for the target(s) of your choice in
+``lib/Target/*/*.td``.
+
+ This is usually a matter of adding a pattern to the .td file that matches the
+ intrinsic, though it may obviously require adding the instructions you want to
+ generate as well. There are lots of examples in the PowerPC and X86 backend
+ to follow.
+
+Adding a new SelectionDAG node
+==============================
+
+As with intrinsics, adding a new SelectionDAG node to LLVM is much easier than
+adding a new instruction. New nodes are often added to help represent
+instructions common to many targets. These nodes often map to an LLVM
+instruction (add, sub) or intrinsic (byteswap, population count). In other
+cases, new nodes have been added to allow many targets to perform a common task
+(converting between floating point and integer representation) or capture more
+complicated behavior in a single node (rotate).
+
+#. ``include/llvm/CodeGen/ISDOpcodes.h``:
+
+ Add an enum value for the new SelectionDAG node.
+
+#. ``lib/CodeGen/SelectionDAG/SelectionDAG.cpp``:
+
+ Add code to print the node to ``getOperationName``. If your new node can be
+ evaluated at compile time when given constant arguments (such as an add of a
+ constant with another constant), find the ``getNode`` method that takes the
+ appropriate number of arguments, and add a case for your node to the switch
+ statement that performs constant folding for nodes that take the same number
+ of arguments as your new node.
+
+#. ``lib/CodeGen/SelectionDAG/LegalizeDAG.cpp``:
+
+ Add code to `legalize, promote, and expand
+ <CodeGenerator.html#selectiondag_legalize>`_ the node as necessary. At a
+ minimum, you will need to add a case statement for your node in
+ ``LegalizeOp`` which calls LegalizeOp on the node's operands, and returns a
+ new node if any of the operands changed as a result of being legalized. It
+ is likely that not all targets supported by the SelectionDAG framework will
+ natively support the new node. In this case, you must also add code in your
+ node's case statement in ``LegalizeOp`` to Expand your node into simpler,
+ legal operations. The case for ``ISD::UREM`` for expanding a remainder into
+ a divide, multiply, and a subtract is a good example.
+
+#. ``lib/CodeGen/SelectionDAG/LegalizeDAG.cpp``:
+
+ If targets may support the new node being added only at certain sizes, you
+ will also need to add code to your node's case statement in ``LegalizeOp``
+ to Promote your node's operands to a larger size, and perform the correct
+ operation. You will also need to add code to ``PromoteOp`` to do this as
+ well. For a good example, see ``ISD::BSWAP``, which promotes its operand to
+ a wider size, performs the byteswap, and then shifts the correct bytes right
+ to emulate the narrower byteswap in the wider type.
+
+#. ``lib/CodeGen/SelectionDAG/LegalizeDAG.cpp``:
+
+ Add a case for your node in ``ExpandOp`` to teach the legalizer how to
+ perform the action represented by the new node on a value that has been split
+ into high and low halves. This case will be used to support your node with a
+ 64 bit operand on a 32 bit target.
+
+#. ``lib/CodeGen/SelectionDAG/DAGCombiner.cpp``:
+
+ If your node can be combined with itself, or other existing nodes in a
+ peephole-like fashion, add a visit function for it, and call that function
+ from. There are several good examples for simple combines you can do;
+ ``visitFABS`` and ``visitSRL`` are good starting places.
+
+#. ``lib/Target/PowerPC/PPCISelLowering.cpp``:
+
+ Each target has an implementation of the ``TargetLowering`` class, usually in
+ its own file (although some targets include it in the same file as the
+ DAGToDAGISel). The default behavior for a target is to assume that your new
+ node is legal for all types that are legal for that target. If this target
+ does not natively support your node, then tell the target to either Promote
+ it (if it is supported at a larger type) or Expand it. This will cause the
+ code you wrote in ``LegalizeOp`` above to decompose your new node into other
+ legal nodes for this target.
+
+#. ``lib/Target/TargetSelectionDAG.td``:
+
+ Most current targets supported by LLVM generate code using the DAGToDAG
+ method, where SelectionDAG nodes are pattern matched to target-specific
+ nodes, which represent individual instructions. In order for the targets to
+ match an instruction to your new node, you must add a def for that node to
+ the list in this file, with the appropriate type constraints. Look at
+ ``add``, ``bswap``, and ``fadd`` for examples.
+
+#. ``lib/Target/PowerPC/PPCInstrInfo.td``:
+
+ Each target has a tablegen file that describes the target's instruction set.
+ For targets that use the DAGToDAG instruction selection framework, add a
+ pattern for your new node that uses one or more target nodes. Documentation
+ for this is a bit sparse right now, but there are several decent examples.
+ See the patterns for ``rotl`` in ``PPCInstrInfo.td``.
+
+#. TODO: document complex patterns.
+
+#. ``llvm/test/Regression/CodeGen/*``:
+
+ Add test cases for your new node to the test suite.
+ ``llvm/test/Regression/CodeGen/X86/bswap.ll`` is a good example.
+
+Adding a new instruction
+========================
+
+.. warning::
+
+ Adding instructions changes the bitcode format, and it will take some effort
+ to maintain compatibility with the previous version. Only add an instruction
+ if it is absolutely necessary.
+
+#. ``llvm/include/llvm/Instruction.def``:
+
+ add a number for your instruction and an enum name
+
+#. ``llvm/include/llvm/Instructions.h``:
+
+ add a definition for the class that will represent your instruction
+
+#. ``llvm/include/llvm/Support/InstVisitor.h``:
+
+ add a prototype for a visitor to your new instruction type
+
+#. ``llvm/lib/AsmParser/Lexer.l``:
+
+ add a new token to parse your instruction from assembly text file
+
+#. ``llvm/lib/AsmParser/llvmAsmParser.y``:
+
+ add the grammar on how your instruction can be read and what it will
+ construct as a result
+
+#. ``llvm/lib/Bitcode/Reader/Reader.cpp``:
+
+ add a case for your instruction and how it will be parsed from bitcode
+
+#. ``llvm/lib/VMCore/Instruction.cpp``:
+
+ add a case for how your instruction will be printed out to assembly
+
+#. ``llvm/lib/VMCore/Instructions.cpp``:
+
+ implement the class you defined in ``llvm/include/llvm/Instructions.h``
+
+#. Test your instruction
+
+#. ``llvm/lib/Target/*``:
+
+ add support for your instruction to code generators, or add a lowering pass.
+
+#. ``llvm/test/Regression/*``:
+
+ add your test cases to the test suite.
+
+Also, you need to implement (or modify) any analyses or passes that you want to
+understand this new instruction.
+
+Adding a new type
+=================
+
+.. warning::
+
+ Adding new types changes the bitcode format, and will break compatibility with
+ currently-existing LLVM installations. Only add new types if it is absolutely
+ necessary.
+
+Adding a fundamental type
+-------------------------
+
+#. ``llvm/include/llvm/Type.h``:
+
+ add enum for the new type; add static ``Type*`` for this type
+
+#. ``llvm/lib/VMCore/Type.cpp``:
+
+ add mapping from ``TypeID`` => ``Type*``; initialize the static ``Type*``
+
+#. ``llvm/lib/AsmReader/Lexer.l``:
+
+ add ability to parse in the type from text assembly
+
+#. ``llvm/lib/AsmReader/llvmAsmParser.y``:
+
+ add a token for that type
+
+Adding a derived type
+---------------------
+
+#. ``llvm/include/llvm/Type.h``:
+
+ add enum for the new type; add a forward declaration of the type also
+
+#. ``llvm/include/llvm/DerivedTypes.h``:
+
+ add new class to represent new class in the hierarchy; add forward
+ declaration to the TypeMap value type
+
+#. ``llvm/lib/VMCore/Type.cpp``:
+
+ add support for derived type to:
+
+ .. code:: c++
+
+ std::string getTypeDescription(const Type &Ty,
+ std::vector<const Type*> &TypeStack)
+ bool TypesEqual(const Type *Ty, const Type *Ty2,
+ std::map<const Type*, const Type*> &EqTypes)
+
+ add necessary member functions for type, and factory methods
+
+#. ``llvm/lib/AsmReader/Lexer.l``:
+
+ add ability to parse in the type from text assembly
+
+#. ``llvm/lib/BitCode/Writer/Writer.cpp``:
+
+ modify ``void BitcodeWriter::outputType(const Type *T)`` to serialize your
+ type
+
+#. ``llvm/lib/BitCode/Reader/Reader.cpp``:
+
+ modify ``const Type *BitcodeReader::ParseType()`` to read your data type
+
+#. ``llvm/lib/VMCore/AsmWriter.cpp``:
+
+ modify
+
+ .. code:: c++
+
+ void calcTypeName(const Type *Ty,
+ std::vector<const Type*> &TypeStack,
+ std::map<const Type*,std::string> &TypeNames,
+ std::string &Result)
+
+ to output the new derived type
diff --git a/docs/GarbageCollection.html b/docs/GarbageCollection.html
index 20f2c96a2b..5bc70f1bb0 100644
--- a/docs/GarbageCollection.html
+++ b/docs/GarbageCollection.html
@@ -1253,7 +1253,7 @@ methods. Here's a realistic example:</p>
>#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/Function.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetAsmInfo.h"
void MyGCPrinter::beginAssembly(std::ostream &amp;OS, AsmPrinter &amp;AP,
@@ -1266,7 +1266,7 @@ void MyGCPrinter::finishAssembly(std::ostream &amp;OS, AsmPrinter &amp;AP,
// Set up for emitting addresses.
const char *AddressDirective;
int AddressAlignLog;
- if (AP.TM.getTargetData()->getPointerSize() == sizeof(int32_t)) {
+ if (AP.TM.getDataLayout()->getPointerSize() == sizeof(int32_t)) {
AddressDirective = TAI.getData32bitsDirective();
AddressAlignLog = 2;
} else {
diff --git a/docs/GettingStarted.html b/docs/GettingStarted.html
deleted file mode 100644
index c91cb03d18..0000000000
--- a/docs/GettingStarted.html
+++ /dev/null
@@ -1,1760 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
- "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <title>Getting Started with LLVM System</title>
- <link rel="stylesheet" href="_static/llvm.css" type="text/css">
-</head>
-<body>
-
-<h1>
- Getting Started with the LLVM System
-</h1>
-
-<ul>
- <li><a href="#overview">Overview</a>
- <li><a href="#quickstart">Getting Started Quickly (A Summary)</a>
- <li><a href="#requirements">Requirements</a>
- <ol>
- <li><a href="#hardware">Hardware</a></li>
- <li><a href="#software">Software</a></li>
- <li><a href="#brokengcc">Broken versions of GCC and other tools</a></li>
- </ol></li>
-
- <li><a href="#starting">Getting Started with LLVM</a>
- <ol>
- <li><a href="#terminology">Terminology and Notation</a></li>
- <li><a href="#environment">Setting Up Your Environment</a></li>
- <li><a href="#unpack">Unpacking the LLVM Archives</a></li>
- <li><a href="#checkout">Checkout LLVM from Subversion</a></li>
- <li><a href="#git_mirror">LLVM GIT mirror</a></li>
- <li><a href="#config">Local LLVM Configuration</a></li>
- <li><a href="#compile">Compiling the LLVM Suite Source Code</a></li>
- <li><a href="#cross-compile">Cross-Compiling LLVM</a></li>
- <li><a href="#objfiles">The Location of LLVM Object Files</a></li>
- <li><a href="#optionalconfig">Optional Configuration Items</a></li>
- </ol></li>
-
- <li><a href="#layout">Program layout</a>
- <ol>
- <li><a href="#examples"><tt>llvm/examples</tt></a></li>
- <li><a href="#include"><tt>llvm/include</tt></a></li>
- <li><a href="#lib"><tt>llvm/lib</tt></a></li>
- <li><a href="#projects"><tt>llvm/projects</tt></a></li>
- <li><a href="#runtime"><tt>llvm/runtime</tt></a></li>
- <li><a href="#test"><tt>llvm/test</tt></a></li>
- <li><a href="#test-suite"><tt>test-suite</tt></a></li>
- <li><a href="#tools"><tt>llvm/tools</tt></a></li>
- <li><a href="#utils"><tt>llvm/utils</tt></a></li>
- </ol></li>
-
- <li><a href="#tutorial">An Example Using the LLVM Tool Chain</a>
- <ol>
- <li><a href="#tutorial4">Example with Clang</a></li>
- </ol>
- <li><a href="#problems">Common Problems</a>
- <li><a href="#links">Links</a>
-</ul>
-
-<div class="doc_author">
- <p>Written by:
- <a href="mailto:criswell@uiuc.edu">John Criswell</a>,
- <a href="mailto:sabre@nondot.org">Chris Lattner</a>,
- <a href="http://misha.brukman.net/">Misha Brukman</a>,
- <a href="http://www.cs.uiuc.edu/~vadve">Vikram Adve</a>, and
- <a href="mailto:gshi1@uiuc.edu">Guochun Shi</a>.
- </p>
-</div>
-
-
-<!-- *********************************************************************** -->
-<h2>
- <a name="overview">Overview</a>
-</h2>
-<!-- *********************************************************************** -->
-
-<div>
-
-<p>Welcome to LLVM! In order to get started, you first need to know some
-basic information.</p>
-
-<p>First, LLVM comes in three pieces. The first piece is the LLVM
-suite. This contains all of the tools, libraries, and header files
-needed to use LLVM. It contains an assembler, disassembler, bitcode
-analyzer and bitcode optimizer. It also contains basic regression tests that
-can be used to test the LLVM tools and the Clang front end.</p>
-
-<p>The second piece is the <a href="http://clang.llvm.org/">Clang</a> front end.
-This component compiles C, C++, Objective C, and Objective C++ code into LLVM
-bitcode. Once compiled into LLVM bitcode, a program can be manipulated with the
-LLVM tools from the LLVM suite.
-</p>
-
-<p>
-There is a third, optional piece called Test Suite. It is a suite of programs
-with a testing harness that can be used to further test LLVM's functionality
-and performance.
-</p>
-
-</div>
-
-<!-- *********************************************************************** -->
-<h2>
- <a name="quickstart">Getting Started Quickly (A Summary)</a>
-</h2>
-<!-- *********************************************************************** -->
-
-<div>
-
-<p>The LLVM Getting Started documentation may be out of date. So, the Clang
-<a href="http://clang.llvm.org/get_started.html">Getting Started</a> page might
-also be a good place to start.</p>
-
-<p>Here's the short story for getting up and running quickly with LLVM:</p>
-
-<ol>
- <li>Read the documentation.</li>
- <li>Read the documentation.</li>
- <li>Remember that you were warned twice about reading the documentation.</li>
-
- <li>Checkout LLVM:
- <ul>
- <li><tt>cd <i>where-you-want-llvm-to-live</i></tt>
- <li><tt>svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm</tt></li>
- </ul>
- </li>
-
- <li>Checkout Clang:
- <ul>
- <li><tt>cd <i>where-you-want-llvm-to-live</i></tt>
- <li><tt>cd llvm/tools</tt>
- <li><tt>svn co http://llvm.org/svn/llvm-project/cfe/trunk clang</tt></li>
- </ul>
- </li>
-
- <li>Checkout Compiler-RT:
- <ul>
- <li><tt>cd <i>where-you-want-llvm-to-live</i></tt>
- <li><tt>cd llvm/projects</tt>
- <li><tt>svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk
- compiler-rt</tt></li>
- </ul>
- </li>
-
- <li>Get the Test Suite Source Code <b>[Optional]</b>
- <ul>
- <li><tt>cd <i>where-you-want-llvm-to-live</i></tt>
- <li><tt>cd llvm/projects</tt>
- <li><tt>svn co http://llvm.org/svn/llvm-project/test-suite/trunk test-suite</tt></li>
- </ul>
- </li>
-
- <li>Configure and build LLVM and Clang:
- <ul>
- <li><tt>cd <i>where-you-want-to-build-llvm</i></tt></li>
- <li><tt>mkdir build</tt> (for building without polluting the source dir)</li>
- <li><tt>cd build</tt></li>
- <li><tt>../llvm/configure [options]</tt>
- <br>Some common options:
-
- <ul>
- <li><tt>--prefix=<i>directory</i></tt> -
- Specify for <i>directory</i> the full pathname of where you
- want the LLVM tools and libraries to be installed (default
- <tt>/usr/local</tt>).</li>
- </ul>
-
- <ul>
- <li><tt>--enable-optimized</tt> -
- Compile with optimizations enabled (default is NO).</li>
- </ul>
-
- <ul>
- <li><tt>--enable-assertions</tt> -
- Compile with assertion checks enabled (default is YES).</li>
- </ul>
- </li>
- <li><tt>make [-j]</tt> - The -j specifies the number of jobs (commands) to
- run simultaneously. This builds both LLVM and Clang for Debug+Asserts mode.
- The --enabled-optimized configure option is used to specify a Release build.</li>
- <li><tt>make check-all</tt> -
- This run the regression tests to ensure everything is in working order.</li>
- <li><tt>make update</tt> -
- This command is used to update all the svn repositories at once, rather then
- having to <tt>cd</tt> into the individual repositories and running
- <tt>svn update</tt>.</li>
- <li>It is also possible to use CMake instead of the makefiles. With CMake
- it is also possible to generate project files for several IDEs: Eclipse
- CDT4, CodeBlocks, Qt-Creator (use the CodeBlocks generator), KDevelop3.</li>
- <li>If you get an "internal compiler error (ICE)" or test failures, see
- <a href="#brokengcc">below</a>.</li>
-
- </ul>
- </li>
-
-</ol>
-
-<p>Consult the <a href="#starting">Getting Started with LLVM</a> section for
-detailed information on configuring and compiling LLVM. See <a
-href="#environment">Setting Up Your Environment</a> for tips that simplify
-working with the Clang front end and LLVM tools. Go to <a href="#layout">Program
-Layout</a> to learn about the layout of the source code tree.</p>
-
-</div>
-
-<!-- *********************************************************************** -->
-<h2>
- <a name="requirements">Requirements</a>
-</h2>
-<!-- *********************************************************************** -->
-
-<div>
-
-<p>Before you begin to use the LLVM system, review the requirements given below.
-This may save you some trouble by knowing ahead of time what hardware and
-software you will need.</p>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="hardware">Hardware</a>
-</h3>
-
-<div>
-
-<p>LLVM is known to work on the following platforms:</p>
-
-<table cellpadding="3" summary="Known LLVM platforms">
-<tr>
- <th>OS</th>
- <th>Arch</th>
- <th>Compilers</th>
-</tr>
-<tr>
- <td>AuroraUX</td>
- <td>x86<sup><a href="#pf_1">1</a></sup></td>
- <td>GCC</td>
-</tr>
-<tr>
- <td>Linux</td>
- <td>x86<sup><a href="#pf_1">1</a></sup></td>
- <td>GCC</td>
-</tr>
-<tr>
- <td>Linux</td>
- <td>amd64</td>
- <td>GCC</td>
-</tr>
-<tr>
- <td>Solaris</td>
- <td>V9 (Ultrasparc)</td>
- <td>GCC</td>
-</tr>
-<tr>
- <td>FreeBSD</td>
- <td>x86<sup><a href="#pf_1">1</a></sup></td>
- <td>GCC</td>
-</tr>
-<tr>
- <td>FreeBSD</td>
- <td>amd64</td>
- <td>GCC</td>
-</tr>
-<tr>
- <td>MacOS X<sup><a href="#pf_2">2</a></sup></td>
- <td>PowerPC</td>
- <td>GCC</td>
-</tr>
-<tr>
- <td>MacOS X<sup><a href="#pf_2">2</a>,<a href="#pf_9">9</a></sup></td>
- <td>x86</td>
- <td>GCC</td>
-</tr>
-<tr>
- <td>Cygwin/Win32</td>
- <td>x86<sup><a href="#pf_1">1</a>,<a href="#pf_8">8</a>,
- <a href="#pf_11">11</a></sup></td>
- <td>GCC 3.4.X, binutils 2.20</td>
-</tr>
-<tr>
- <td>MinGW/Win32</td>
- <td>x86<sup><a href="#pf_1">1</a>,<a href="#pf_6">6</a>,
- <a href="#pf_8">8</a>, <a href="#pf_10">10</a>,
- <a href="#pf_11">11</a></sup></td>
- <td>GCC 3.4.X, binutils 2.20</td>
-</tr>
-</table>
-
-<p>LLVM has partial support for the following platforms:</p>
-
-<table summary="LLVM partial platform support">
-<tr>
- <th>OS</th>
- <th>Arch</th>
- <th>Compilers</th>
-</tr>
-<tr>
- <td>Windows</td>
- <td>x86<sup><a href="#pf_1">1</a></sup></td>
- <td>Visual Studio 2008 or higher<sup><a href="#pf_4">4</a>,<a href="#pf_5">5</a></sup></td>
-<tr>
- <td>AIX<sup><a href="#pf_3">3</a>,<a href="#pf_4">4</a></sup></td>
- <td>PowerPC</td>
- <td>GCC</td>
-</tr>
-<tr>
- <td>Linux<sup><a href="#pf_3">3</a>,<a href="#pf_5">5</a></sup></td>
- <td>PowerPC</td>
- <td>GCC</td>
-</tr>
-
-<tr>
- <td>Linux<sup><a href="#pf_7">7</a></sup></td>
- <td>Alpha</td>
- <td>GCC</td>
-</tr>
-<tr>
- <td>Linux<sup><a href="#pf_7">7</a></sup></td>
- <td>Itanium (IA-64)</td>
- <td>GCC</td>
-</tr>
-<tr>
- <td>HP-UX<sup><a href="#pf_7">7</a></sup></td>
- <td>Itanium (IA-64)</td>
- <td>HP aCC</td>
-</tr>
-<tr>
- <td>Windows x64</td>
- <td>x86-64</td>
- <td>mingw-w64's GCC-4.5.x<sup><a href="#pf_12">12</a></sup></td>
-</tr>
-</table>
-
-<p><b>Notes:</b></p>
-
-<div class="doc_notes">
-<ol>
-<li><a name="pf_1">Code generation supported for Pentium processors and
-up</a></li>
-<li><a name="pf_2">Code generation supported for 32-bit ABI only</a></li>
-<li><a name="pf_3">No native code generation</a></li>
-<li><a name="pf_4">Build is not complete: one or more tools do not link or function</a></li>
-<li><a name="pf_5">The GCC-based C/C++ frontend does not build</a></li>
-<li><a name="pf_6">The port is done using the MSYS shell.</a></li>
-<li><a name="pf_7">Native code generation exists but is not complete.</a></li>
-<li><a name="pf_8">Binutils 2.20 or later is required to build the assembler
- generated by LLVM properly.</a></li>
-<li><a name="pf_9">Xcode 2.5 and gcc 4.0.1</a> (Apple Build 5370) will trip
- internal LLVM assert messages when compiled for Release at optimization
- levels greater than 0 (i.e., <i>"-O1"</i> and higher).
- Add <i>OPTIMIZE_OPTION="-O0"</i> to the build command line
- if compiling for LLVM Release or bootstrapping the LLVM toolchain.</li>
-<li><a name="pf_10">For MSYS/MinGW on Windows, be sure to install the MSYS
- version of the perl package, and be sure it appears in your path
- before any Windows-based versions such as Strawberry Perl and
- ActivePerl, as these have Windows-specifics that will cause the
- build to fail.</a></li>
-<li><a name="pf_11">To use LLVM modules on Win32-based system,
- you may configure LLVM with <i>&quot;--enable-shared&quot;</i>.</a></li>
-<li><a name="pf_12">To compile SPU backend, you need to add
- <tt>&quot;LDFLAGS=-Wl,--stack,16777216&quot;</tt> to configure.</a></li>
-</ol>
-</div>
-
-<p>Note that you will need about 1-3 GB of space for a full LLVM build in Debug
-mode, depending on the system (it is so large because of all the debugging
-information and the fact that the libraries are statically linked into multiple
-tools). If you do not need many of the tools and you are space-conscious, you
-can pass <tt>ONLY_TOOLS="tools you need"</tt> to make. The Release build
-requires considerably less space.</p>
-
-<p>The LLVM suite <i>may</i> compile on other platforms, but it is not
-guaranteed to do so. If compilation is successful, the LLVM utilities should be
-able to assemble, disassemble, analyze, and optimize LLVM bitcode. Code
-generation should work as well, although the generated native code may not work
-on your platform.</p>
-
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="software">Software</a>
-</h3>
-<div>
- <p>Compiling LLVM requires that you have several software packages
- installed. The table below lists those required packages. The Package column
- is the usual name for the software package that LLVM depends on. The Version
- column provides "known to work" versions of the package. The Notes column
- describes how LLVM uses the package and provides other details.</p>
- <table summary="Packages required to compile LLVM">
- <tr><th>Package</th><th>Version</th><th>Notes</th></tr>
-
- <tr>
- <td><a href="http://savannah.gnu.org/projects/make">GNU Make</a></td>
- <td>3.79, 3.79.1</td>
- <td>Makefile/build processor</td>
- </tr>
-
- <tr>
- <td><a href="http://gcc.gnu.org/">GCC</a></td>
- <td>3.4.2</td>
- <td>C/C++ compiler<sup><a href="#sf1">1</a></sup></td>
- </tr>
-
- <tr>
- <td><a href="http://www.gnu.org/software/texinfo/">TeXinfo</a></td>
- <td>4.5</td>
- <td>For building the CFE</td>
- </tr>
-
- <tr>
- <td><a href="http://subversion.tigris.org/project_packages.html">SVN</a></td>
- <td>&ge;1.3</td>
- <td>Subversion access to LLVM<sup><a href="#sf2">2</a></sup></td>
- </tr>
-
- <!-- FIXME:
- Do we support dg?
- Are DejaGnu and expect obsolete?
- Shall we mention Python? -->
-
- <tr>
- <td><a href="http://savannah.gnu.org/projects/dejagnu">DejaGnu</a></td>
- <td>1.4.2</td>
- <td>Automated test suite<sup><a href="#sf3">3</a></sup></td>
- </tr>
-
- <tr>
- <td><a href="http://www.tcl.tk/software/tcltk/">tcl</a></td>
- <td>8.3, 8.4</td>
- <td>Automated test suite<sup><a href="#sf3">3</a></sup></td>
- </tr>
-
- <tr>
- <td><a href="http://expect.nist.gov/">expect</a></td>
- <td>5.38.0</td>
- <td>Automated test suite<sup><a href="#sf3">3</a></sup></td>
- </tr>
-
- <tr>
- <td><a href="http://www.perl.com/download.csp">perl</a></td>
- <td>&ge;5.6.0</td>
- <td>Utilities</td>
- </tr>
-
- <tr>
- <td><a href="http://savannah.gnu.org/projects/m4">GNU M4</a>
- <td>1.4</td>
- <td>Macro processor for configuration<sup><a href="#sf4">4</a></sup></td>
- </tr>
-
- <tr>
- <td><a href="http://www.gnu.org/software/autoconf/">GNU Autoconf</a></td>
- <td>2.60</td>
- <td>Configuration script builder<sup><a href="#sf4">4</a></sup></td>
- </tr>
-
- <tr>
- <td><a href="http://www.gnu.org/software/automake/">GNU Automake</a></td>
- <td>1.9.6</td>
- <td>aclocal macro generator<sup><a href="#sf4">4</a></sup></td>
- </tr>
-
- <tr>
- <td><a href="http://savannah.gnu.org/projects/libtool">libtool</a></td>
- <td>1.5.22</td>
- <td>Shared library manager<sup><a href="#sf4">4</a></sup></td>
- </tr>
-
- </table>
-
- <p><b>Notes:</b></p>
- <div class="doc_notes">
- <ol>
- <li><a name="sf1">Only the C and C++ languages are needed so there's no
- need to build the other languages for LLVM's purposes.</a> See
- <a href="#brokengcc">below</a> for specific version info.</li>
- <li><a name="sf2">You only need Subversion if you intend to build from the
- latest LLVM sources. If you're working from a release distribution, you
- don't need Subversion.</a></li>
- <li><a name="sf3">Only needed if you want to run the automated test
- suite in the <tt>llvm/test</tt> directory.</a></li>
- <li><a name="sf4">If you want to make changes to the configure scripts,
- you will need GNU autoconf (2.60), and consequently, GNU M4 (version 1.4
- or higher). You will also need automake (1.9.6). We only use aclocal
- from that package.</a></li>
- </ol>
- </div>
-
- <p>Additionally, your compilation host is expected to have the usual
- plethora of Unix utilities. Specifically:</p>
- <ul>
- <li><b>ar</b> - archive library builder</li>
- <li><b>bzip2*</b> - bzip2 command for distribution generation</li>
- <li><b>bunzip2*</b> - bunzip2 command for distribution checking</li>
- <li><b>chmod</b> - change permissions on a file</li>
- <li><b>cat</b> - output concatenation utility</li>
- <li><b>cp</b> - copy files</li>
- <li><b>date</b> - print the current date/time </li>
- <li><b>echo</b> - print to standard output</li>
- <li><b>egrep</b> - extended regular expression search utility</li>
- <li><b>find</b> - find files/dirs in a file system</li>
- <li><b>grep</b> - regular expression search utility</li>
- <li><b>gzip*</b> - gzip command for distribution generation</li>
- <li><b>gunzip*</b> - gunzip command for distribution checking</li>
- <li><b>install</b> - install directories/files </li>
- <li><b>mkdir</b> - create a directory</li>
- <li><b>mv</b> - move (rename) files</li>
- <li><b>ranlib</b> - symbol table builder for archive libraries</li>
- <li><b>rm</b> - remove (delete) files and directories</li>
- <li><b>sed</b> - stream editor for transforming output</li>
- <li><b>sh</b> - Bourne shell for make build scripts</li>
- <li><b>tar</b> - tape archive for distribution generation</li>
- <li><b>test</b> - test things in file system</li>
- <li><b>unzip*</b> - unzip command for distribution checking</li>
- <li><b>zip*</b> - zip command for distribution generation</li>
- </ul>
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="brokengcc">Broken versions of GCC and other tools</a>
-</h3>
-
-<div>
-
-<p>LLVM is very demanding of the host C++ compiler, and as such tends to expose
-bugs in the compiler. In particular, several versions of GCC crash when trying
-to compile LLVM. We routinely use GCC 4.2 (and higher) or Clang.
-Other versions of GCC will probably work as well. GCC versions listed
-here are known to not work. If you are using one of these versions, please try
-to upgrade your GCC to something more recent. If you run into a problem with a
-version of GCC not listed here, please <a href="mailto:llvmdev@cs.uiuc.edu">let
-us know</a>. Please use the "<tt>gcc -v</tt>" command to find out which version
-of GCC you are using.
-</p>
-
-<p><b>GCC versions prior to 3.0</b>: GCC 2.96.x and before had several
-problems in the STL that effectively prevent it from compiling LLVM.
-</p>
-
-<p><b>GCC 3.2.2 and 3.2.3</b>: These versions of GCC fails to compile LLVM with
-a bogus template error. This was fixed in later GCCs.</p>
-
-<p><b>GCC 3.3.2</b>: This version of GCC suffered from a <a
-href="http://gcc.gnu.org/PR13392">serious bug</a> which causes it to crash in
-the "<tt>convert_from_eh_region_ranges_1</tt>" GCC function.</p>
-
-<p><b>Cygwin GCC 3.3.3</b>: The version of GCC 3.3.3 commonly shipped with
- Cygwin does not work.</p>
-<p><b>SuSE GCC 3.3.3</b>: The version of GCC 3.3.3 shipped with SuSE 9.1 (and
- possibly others) does not compile LLVM correctly (it appears that exception
- handling is broken in some cases). Please download the FSF 3.3.3 or upgrade
- to a newer version of GCC.</p>
-<p><b>GCC 3.4.0 on linux/x86 (32-bit)</b>: GCC miscompiles portions of the
- code generator, causing an infinite loop in the llvm-gcc build when built
- with optimizations enabled (i.e. a release build).</p>
-<p><b>GCC 3.4.2 on linux/x86 (32-bit)</b>: GCC miscompiles portions of the
- code generator at -O3, as with 3.4.0. However gcc 3.4.2 (unlike 3.4.0)
- correctly compiles LLVM at -O2. A work around is to build release LLVM
- builds with "make ENABLE_OPTIMIZED=1 OPTIMIZE_OPTION=-O2 ..."</p>
-<p><b>GCC 3.4.x on X86-64/amd64</b>: GCC <a href="http://llvm.org/PR1056">
- miscompiles portions of LLVM</a>.</p>
-<p><b>GCC 3.4.4 (CodeSourcery ARM 2005q3-2)</b>: this compiler miscompiles LLVM
- when building with optimizations enabled. It appears to work with
- "<tt>make ENABLE_OPTIMIZED=1 OPTIMIZE_OPTION=-O1</tt>" or build a debug
- build.</p>
-<p><b>IA-64 GCC 4.0.0</b>: The IA-64 version of GCC 4.0.0 is known to
- miscompile LLVM.</p>
-<p><b>Apple Xcode 2.3</b>: GCC crashes when compiling LLVM at -O3 (which is the
- default with ENABLE_OPTIMIZED=1. To work around this, build with
- "ENABLE_OPTIMIZED=1 OPTIMIZE_OPTION=-O2".</p>
-<p><b>GCC 4.1.1</b>: GCC fails to build LLVM with template concept check errors
- compiling some files. At the time of this writing, GCC mainline (4.2)
- did not share the problem.</p>
-<p><b>GCC 4.1.1 on X86-64/amd64</b>: GCC <a href="http://llvm.org/PR1063">
- miscompiles portions of LLVM</a> when compiling llvm itself into 64-bit
- code. LLVM will appear to mostly work but will be buggy, e.g. failing
- portions of its testsuite.</p>
-<p><b>GCC 4.1.2 on OpenSUSE</b>: Seg faults during libstdc++ build and on x86_64
-platforms compiling md5.c gets a mangled constant.</p>
-<p><b>GCC 4.1.2 (20061115 (prerelease) (Debian 4.1.1-21)) on Debian</b>: Appears
-to miscompile parts of LLVM 2.4. One symptom is ValueSymbolTable complaining
-about symbols remaining in the table on destruction.</p>
-<p><b>GCC 4.1.2 20071124 (Red Hat 4.1.2-42)</b>: Suffers from the same symptoms
-as the previous one. It appears to work with ENABLE_OPTIMIZED=0 (the default).</p>
-<p><b>Cygwin GCC 4.3.2 20080827 (beta) 2</b>:
- Users <a href="http://llvm.org/PR4145">reported</a> various problems related
- with link errors when using this GCC version.</p>
-<p><b>Debian GCC 4.3.2 on X86</b>: Crashes building some files in LLVM 2.6.</p>
-<p><b>GCC 4.3.3 (Debian 4.3.3-10) on ARM</b>: Miscompiles parts of LLVM 2.6
-when optimizations are turned on. The symptom is an infinite loop in
-FoldingSetImpl::RemoveNode while running the code generator.</p>
-<p><b>SUSE 11 GCC 4.3.4</b>: Miscompiles LLVM, causing crashes in ValueHandle logic.</p>
-<p><b>GCC 4.3.5 and GCC 4.4.5 on ARM</b>: These can miscompile <tt>value >>
-1</tt> even at -O0. A test failure in <tt>test/Assembler/alignstack.ll</tt> is
-one symptom of the problem.
-<p><b>GNU ld 2.16.X</b>. Some 2.16.X versions of the ld linker will produce very
-long warning messages complaining that some ".gnu.linkonce.t.*" symbol was
-defined in a discarded section. You can safely ignore these messages as they are
-erroneous and the linkage is correct. These messages disappear using ld
-2.17.</p>
-
-<p><b>GNU binutils 2.17</b>: Binutils 2.17 contains <a
-href="http://sourceware.org/bugzilla/show_bug.cgi?id=3111">a bug</a> which
-causes huge link times (minutes instead of seconds) when building LLVM. We
-recommend upgrading to a newer version (2.17.50.0.4 or later).</p>
-
-<p><b>GNU Binutils 2.19.1 Gold</b>: This version of Gold contained
-<a href="http://sourceware.org/bugzilla/show_bug.cgi?id=9836">a bug</a>
-which causes intermittent failures when building LLVM with position independent
-code. The symptom is an error about cyclic dependencies. We recommend
-upgrading to a newer version of Gold.</p>
-
-</div>
-
-</div>
-
-<!-- *********************************************************************** -->
-<h2>
- <a name="starting">Getting Started with LLVM</a>
-</h2>
-<!-- *********************************************************************** -->
-
-<div>
-
-<p>The remainder of this guide is meant to get you up and running with
-LLVM and to give you some basic information about the LLVM environment.</p>
-
-<p>The later sections of this guide describe the <a
-href="#layout">general layout</a> of the LLVM source tree, a <a
-href="#tutorial">simple example</a> using the LLVM tool chain, and <a
-href="#links">links</a> to find more information about LLVM or to get
-help via e-mail.</p>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="terminology">Terminology and Notation</a>
-</h3>
-
-<div>
-
-<p>Throughout this manual, the following names are used to denote paths
-specific to the local system and working environment. <i>These are not
-environment variables you need to set but just strings used in the rest
-of this document below</i>. In any of the examples below, simply replace
-each of these names with the appropriate pathname on your local system.
-All these paths are absolute:</p>
-
-<dl>
- <dt>SRC_ROOT
- <dd>
- This is the top level directory of the LLVM source tree.
- <br><br>
-
- <dt>OBJ_ROOT
- <dd>
- This is the top level directory of the LLVM object tree (i.e. the
- tree where object files and compiled programs will be placed. It
- can be the same as SRC_ROOT).
- <br><br>
-
-</dl>
-
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="environment">Setting Up Your Environment</a>
-</h3>
-
-<div>
-
-<p>
-In order to compile and use LLVM, you may need to set some environment
-variables.
-
-<dl>
- <dt><tt>LLVM_LIB_SEARCH_PATH</tt>=<tt>/path/to/your/bitcode/libs</tt></dt>
- <dd>[Optional] This environment variable helps LLVM linking tools find the
- locations of your bitcode libraries. It is provided only as a
- convenience since you can specify the paths using the -L options of the
- tools and the C/C++ front-end will automatically use the bitcode files
- installed in its
- <tt>lib</tt> directory.</dd>
-</dl>
-
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="unpack">Unpacking the LLVM Archives</a>
-</h3>
-
-<div>
-
-<p>
-If you have the LLVM distribution, you will need to unpack it before you
-can begin to compile it. LLVM is distributed as a set of two files: the LLVM
-suite and the LLVM GCC front end compiled for your platform. There is an
-additional test suite that is optional. Each file is a TAR archive that is
-compressed with the gzip program.
-</p>
-
-<p>The files are as follows, with <em>x.y</em> marking the version number:
-<dl>
- <dt><tt>llvm-x.y.tar.gz</tt></dt>
- <dd>Source release for the LLVM libraries and tools.<br></dd>
-
- <dt><tt>llvm-test-x.y.tar.gz</tt></dt>
- <dd>Source release for the LLVM test-suite.</dd>
-
- <dt><tt>llvm-gcc-4.2-x.y.source.tar.gz</tt></dt>
- <dd>Source release of the llvm-gcc-4.2 front end. See README.LLVM in the root
- directory for build instructions.<br></dd>
-
- <dt><tt>llvm-gcc-4.2-x.y-platform.tar.gz</tt></dt>
- <dd>Binary release of the llvm-gcc-4.2 front end for a specific platform.<br></dd>
-
-</dl>
-
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="checkout">Checkout LLVM from Subversion</a>
-</h3>
-
-<div>
-
-<p>If you have access to our Subversion repository, you can get a fresh copy of
-the entire source code. All you need to do is check it out from Subversion as
-follows:</p>
-
-<ul>
- <li><tt>cd <i>where-you-want-llvm-to-live</i></tt></li>
- <li>Read-Only: <tt>svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm</tt></li>
- <li>Read-Write:<tt>svn co https://user@llvm.org/svn/llvm-project/llvm/trunk
- llvm</tt></li>
-</ul>
-
-
-<p>This will create an '<tt>llvm</tt>' directory in the current
-directory and fully populate it with the LLVM source code, Makefiles,
-test directories, and local copies of documentation files.</p>
-
-<p>If you want to get a specific release (as opposed to the most recent
-revision), you can checkout it from the '<tt>tags</tt>' directory (instead of
-'<tt>trunk</tt>'). The following releases are located in the following
-subdirectories of the '<tt>tags</tt>' directory:</p>
-
-<ul>
-<li>Release 3.1: <b>RELEASE_31/final</b></li>
-<li>Release 3.0: <b>RELEASE_30/final</b></li>
-<li>Release 2.9: <b>RELEASE_29/final</b></li>
-<li>Release 2.8: <b>RELEASE_28</b></li>
-<li>Release 2.7: <b>RELEASE_27</b></li>
-<li>Release 2.6: <b>RELEASE_26</b></li>
-<li>Release 2.5: <b>RELEASE_25</b></li>
-<li>Release 2.4: <b>RELEASE_24</b></li>
-<li>Release 2.3: <b>RELEASE_23</b></li>
-<li>Release 2.2: <b>RELEASE_22</b></li>
-<li>Release 2.1: <b>RELEASE_21</b></li>
-<li>Release 2.0: <b>RELEASE_20</b></li>
-<li>Release 1.9: <b>RELEASE_19</b></li>
-<li>Release 1.8: <b>RELEASE_18</b></li>
-<li>Release 1.7: <b>RELEASE_17</b></li>
-<li>Release 1.6: <b>RELEASE_16</b></li>
-<li>Release 1.5: <b>RELEASE_15</b></li>
-<li>Release 1.4: <b>RELEASE_14</b></li>
-<li>Release 1.3: <b>RELEASE_13</b></li>
-<li>Release 1.2: <b>RELEASE_12</b></li>
-<li>Release 1.1: <b>RELEASE_11</b></li>
-<li>Release 1.0: <b>RELEASE_1</b></li>
-</ul>
-
-<p>If you would like to get the LLVM test suite (a separate package as of 1.4),
-you get it from the Subversion repository:</p>
-
-<div class="doc_code">
-<pre>
-% cd llvm/projects
-% svn co http://llvm.org/svn/llvm-project/test-suite/trunk test-suite
-</pre>
-</div>
-
-<p>By placing it in the <tt>llvm/projects</tt>, it will be automatically
-configured by the LLVM configure script as well as automatically updated when
-you run <tt>svn update</tt>.</p>
-
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="git_mirror">GIT mirror</a>
-</h3>
-
-<div>
-
-<p>GIT mirrors are available for a number of LLVM subprojects. These mirrors
- sync automatically with each Subversion commit and contain all necessary
- git-svn marks (so, you can recreate git-svn metadata locally). Note that right
- now mirrors reflect only <tt>trunk</tt> for each project. You can do the
- read-only GIT clone of LLVM via:</p>
-
-<pre class="doc_code">
-git clone http://llvm.org/git/llvm.git
-</pre>
-
-<p>If you want to check out clang too, run:</p>
-
-<pre class="doc_code">
-git clone http://llvm.org/git/llvm.git
-cd llvm/tools
-git clone http://llvm.org/git/clang.git
-</pre>
-
-<p>
-Since the upstream repository is in Subversion, you should use
-<tt>&quot;git pull --rebase&quot;</tt>
-instead of <tt>&quot;git pull&quot;</tt> to avoid generating a non-linear
-history in your clone.
-To configure <tt>&quot;git pull&quot;</tt> to pass <tt>--rebase</tt> by default
-on the master branch, run the following command:
-</p>
-
-<pre class="doc_code">
-git config branch.master.rebase true
-</pre>
-
-<h4>Sending patches with Git</h4>
-<div>
-<p>
-Please read <a href="DeveloperPolicy.html#patches">Developer Policy</a>, too.
-</p>
-
-<p>
-Assume <tt>master</tt> points the upstream and <tt>mybranch</tt> points your
-working branch, and <tt>mybranch</tt> is rebased onto <tt>master</tt>.
-At first you may check sanity of whitespaces:
-</p>
-
-<pre class="doc_code">
-git diff --check master..mybranch
-</pre>
-
-<p>
-The easiest way to generate a patch is as below:
-</p>
-
-<pre class="doc_code">
-git diff master..mybranch &gt; /path/to/mybranch.diff
-</pre>
-
-<p>
-It is a little different from svn-generated diff. git-diff-generated diff has
-prefixes like <tt>a/</tt> and <tt>b/</tt>. Don't worry, most developers might
-know it could be accepted with <tt>patch -p1 -N</tt>.
-</p>
-
-<p>
-But you may generate patchset with git-format-patch. It generates
-by-each-commit patchset. To generate patch files to attach to your article:
-</p>
-
-<pre class="doc_code">
-git format-patch --no-attach master..mybranch -o /path/to/your/patchset
-</pre>
-
-<p>
-If you would like to send patches directly, you may use git-send-email or
-git-imap-send. Here is an example to generate the patchset in Gmail's [Drafts].
-</p>
-
-<pre class="doc_code">
-git format-patch --attach master..mybranch --stdout | git imap-send
-</pre>
-
-<p>
-Then, your .git/config should have [imap] sections.
-</p>
-
-<pre class="doc_code">
-[imap]
- host = imaps://imap.gmail.com
- user = <em>your.gmail.account</em>@gmail.com
- pass = <em>himitsu!</em>
- port = 993
- sslverify = false
-; in English
- folder = "[Gmail]/Drafts"
-; example for Japanese, "Modified UTF-7" encoded.
- folder = "[Gmail]/&amp;Tgtm+DBN-"
-; example for Traditional Chinese
- folder = "[Gmail]/&amp;g0l6Pw-"
-</pre>
-
-</div>
-
-<h4>For developers to work with git-svn</h4>
-<div>
-
-<p>To set up clone from which you can submit code using
- <tt>git-svn</tt>, run:</p>
-
-<pre class="doc_code">
-git clone http://llvm.org/git/llvm.git
-cd llvm
-git svn init https://llvm.org/svn/llvm-project/llvm/trunk --username=&lt;username>
-git config svn-remote.svn.fetch :refs/remotes/origin/master
-git svn rebase -l # -l avoids fetching ahead of the git mirror.
-
-# If you have clang too:
-cd tools
-git clone http://llvm.org/git/clang.git
-cd clang
-git svn init https://llvm.org/svn/llvm-project/cfe/trunk --username=&lt;username>
-git config svn-remote.svn.fetch :refs/remotes/origin/master
-git svn rebase -l
-</pre>
-
-<p>To update this clone without generating git-svn tags that conflict
-with the upstream git repo, run:</p>
-
-<pre class="doc_code">
-git fetch && (cd tools/clang && git fetch) # Get matching revisions of both trees.
-git checkout master
-git svn rebase -l
-(cd tools/clang &&
- git checkout master &&
- git svn rebase -l)
-</pre>
-
-<p>This leaves your working directories on their master branches, so
-you'll need to <tt>checkout</tt> each working branch individually and
-<tt>rebase</tt> it on top of its parent branch. (Note: This script is
-intended for relative newbies to git. If you have more experience,
-you can likely improve on it.)</p>
-
-<p>The git-svn metadata can get out of sync after you mess around with
-branches and <code>dcommit</code>. When that happens, <code>git svn
-dcommit</code> stops working, complaining about files with uncommitted
-changes. The fix is to rebuild the metadata:</p>
-
-<pre class="doc_code">
-rm -rf .git/svn
-git svn rebase -l
-</pre>
-
-</div>
-
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="config">Local LLVM Configuration</a>
-</h3>
-
-<div>
-
- <p>Once checked out from the Subversion repository, the LLVM suite source
- code must be
-configured via the <tt>configure</tt> script. This script sets variables in the
-various <tt>*.in</tt> files, most notably <tt>llvm/Makefile.config</tt> and
-<tt>llvm/include/Config/config.h</tt>. It also populates <i>OBJ_ROOT</i> with
-the Makefiles needed to begin building LLVM.</p>
-
-<p>The following environment variables are used by the <tt>configure</tt>
-script to configure the build system:</p>
-
-<table summary="LLVM configure script environment variables">
- <tr><th>Variable</th><th>Purpose</th></tr>
- <tr>
- <td>CC</td>
- <td>Tells <tt>configure</tt> which C compiler to use. By default,
- <tt>configure</tt> will look for the first GCC C compiler in
- <tt>PATH</tt>. Use this variable to override
- <tt>configure</tt>'s default behavior.</td>
- </tr>
- <tr>
- <td>CXX</td>
- <td>Tells <tt>configure</tt> which C++ compiler to use. By default,
- <tt>configure</tt> will look for the first GCC C++ compiler in
- <tt>PATH</tt>. Use this variable to override
- <tt>configure</tt>'s default behavior.</td>
- </tr>
-</table>
-
-<p>The following options can be used to set or enable LLVM specific options:</p>
-
-<dl>
- <dt><i>--enable-optimized</i></dt>
- <dd>
- Enables optimized compilation (debugging symbols are removed
- and GCC optimization flags are enabled). Note that this is the default
- setting if you are using the LLVM distribution. The default behavior
- of an Subversion checkout is to use an unoptimized build (also known as a
- debug build).
- <br><br>
- </dd>
- <dt><i>--enable-debug-runtime</i></dt>
- <dd>
- Enables debug symbols in the runtime libraries. The default is to strip
- debug symbols from the runtime libraries.
- </dd>
- <dt><i>--enable-jit</i></dt>
- <dd>
- Compile the Just In Time (JIT) compiler functionality. This is not
- available
- on all platforms. The default is dependent on platform, so it is best
- to explicitly enable it if you want it.
- <br><br>
- </dd>
- <dt><i>--enable-targets=</i><tt>target-option</tt></dt>
- <dd>Controls which targets will be built and linked into llc. The default
- value for <tt>target_options</tt> is "all" which builds and links all
- available targets. The value "host-only" can be specified to build only a
- native compiler (no cross-compiler targets available). The "native" target is
- selected as the target of the build host. You can also specify a comma
- separated list of target names that you want available in llc. The target
- names use all lower case. The current set of targets is: <br>
- <tt>arm, cpp, hexagon, mblaze, mips, mipsel, msp430, powerpc, ptx, sparc, spu, x86, x86_64, xcore</tt>.
- <br><br></dd>
- <dt><i>--enable-doxygen</i></dt>
- <dd>Look for the doxygen program and enable construction of doxygen based
- documentation from the source code. This is disabled by default because
- generating the documentation can take a long time and producess 100s of
- megabytes of output.</dd>
- <dt><i>--with-udis86</i></dt>
- <dd>LLVM can use external disassembler library for various purposes (now it's
- used only for examining code produced by JIT). This option will enable usage
- of <a href="http://udis86.sourceforge.net/">udis86</a> x86 (both 32 and 64
- bits) disassembler library.</dd>
-</dl>
-
-<p>To configure LLVM, follow these steps:</p>
-
-<ol>
- <li><p>Change directory into the object root directory:</p>
-
- <div class="doc_code"><pre>% cd <i>OBJ_ROOT</i></pre></div></li>
-
- <li><p>Run the <tt>configure</tt> script located in the LLVM source
- tree:</p>
-
- <div class="doc_code">
- <pre>% <i>SRC_ROOT</i>/configure --prefix=/install/path [other options]</pre>
- </div></li>
-</ol>
-
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="compile">Compiling the LLVM Suite Source Code</a>
-</h3>
-
-<div>
-
-<p>Once you have configured LLVM, you can build it. There are three types of
-builds:</p>
-
-<dl>
- <dt>Debug Builds
- <dd>
- These builds are the default when one is using an Subversion checkout and
- types <tt>gmake</tt> (unless the <tt>--enable-optimized</tt> option was
- used during configuration). The build system will compile the tools and
- libraries with debugging information. To get a Debug Build using the
- LLVM distribution the <tt>--disable-optimized</tt> option must be passed
- to <tt>configure</tt>.
- <br><br>
-
- <dt>Release (Optimized) Builds
- <dd>
- These builds are enabled with the <tt>--enable-optimized</tt> option to
- <tt>configure</tt> or by specifying <tt>ENABLE_OPTIMIZED=1</tt> on the
- <tt>gmake</tt> command line. For these builds, the build system will
- compile the tools and libraries with GCC optimizations enabled and strip
- debugging information from the libraries and executables it generates.
- Note that Release Builds are default when using an LLVM distribution.
- <br><br>
-
- <dt>Profile Builds
- <dd>
- These builds are for use with profiling. They compile profiling
- information into the code for use with programs like <tt>gprof</tt>.
- Profile builds must be started by specifying <tt>ENABLE_PROFILING=1</tt>
- on the <tt>gmake</tt> command line.
-</dl>
-
-<p>Once you have LLVM configured, you can build it by entering the
-<i>OBJ_ROOT</i> directory and issuing the following command:</p>
-
-<div class="doc_code"><pre>% gmake</pre></div>
-
-<p>If the build fails, please <a href="#brokengcc">check here</a> to see if you
-are using a version of GCC that is known not to compile LLVM.</p>
-
-<p>
-If you have multiple processors in your machine, you may wish to use some of
-the parallel build options provided by GNU Make. For example, you could use the
-command:</p>
-
-<div class="doc_code"><pre>% gmake -j2</pre></div>
-
-<p>There are several special targets which are useful when working with the LLVM
-source code:</p>
-
-<dl>
- <dt><tt>gmake clean</tt>
- <dd>
- Removes all files generated by the build. This includes object files,
- generated C/C++ files, libraries, and executables.
- <br><br>
-
- <dt><tt>gmake dist-clean</tt>
- <dd>
- Removes everything that <tt>gmake clean</tt> does, but also removes files
- generated by <tt>configure</tt>. It attempts to return the source tree to the
- original state in which it was shipped.
- <br><br>
-
- <dt><tt>gmake install</tt>
- <dd>
- Installs LLVM header files, libraries, tools, and documentation in a
- hierarchy
- under $PREFIX, specified with <tt>./configure --prefix=[dir]</tt>, which
- defaults to <tt>/usr/local</tt>.
- <br><br>
-
- <dt><tt>gmake -C runtime install-bytecode</tt>
- <dd>
- Assuming you built LLVM into $OBJDIR, when this command is run, it will
- install bitcode libraries into the GCC front end's bitcode library
- directory. If you need to update your bitcode libraries,
- this is the target to use once you've built them.
- <br><br>
-</dl>
-
-<p>Please see the <a href="MakefileGuide.html">Makefile Guide</a> for further
-details on these <tt>make</tt> targets and descriptions of other targets
-available.</p>
-
-<p>It is also possible to override default values from <tt>configure</tt> by
-declaring variables on the command line. The following are some examples:</p>
-
-<dl>
- <dt><tt>gmake ENABLE_OPTIMIZED=1</tt>
- <dd>
- Perform a Release (Optimized) build.
- <br><br>
-
- <dt><tt>gmake ENABLE_OPTIMIZED=1 DISABLE_ASSERTIONS=1</tt>
- <dd>
- Perform a Release (Optimized) build without assertions enabled.
- <br><br>
-
- <dt><tt>gmake ENABLE_OPTIMIZED=0</tt>
- <dd>
- Perform a Debug build.
- <br><br>
-
- <dt><tt>gmake ENABLE_PROFILING=1</tt>
- <dd>
- Perform a Profiling build.
- <br><br>
-
- <dt><tt>gmake VERBOSE=1</tt>
- <dd>
- Print what <tt>gmake</tt> is doing on standard output.
- <br><br>
-
- <dt><tt>gmake TOOL_VERBOSE=1</tt></dt>
- <dd>Ask each tool invoked by the makefiles to print out what it is doing on
- the standard output. This also implies <tt>VERBOSE=1</tt>.
- <br><br></dd>
-</dl>
-
-<p>Every directory in the LLVM object tree includes a <tt>Makefile</tt> to build
-it and any subdirectories that it contains. Entering any directory inside the
-LLVM object tree and typing <tt>gmake</tt> should rebuild anything in or below
-that directory that is out of date.</p>
-
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="cross-compile">Cross-Compiling LLVM</a>
-</h3>
-
-<div>
- <p>It is possible to cross-compile LLVM itself. That is, you can create LLVM
- executables and libraries to be hosted on a platform different from the
- platform where they are build (a Canadian Cross build). To configure a
- cross-compile, supply the configure script with <tt>--build</tt> and
- <tt>--host</tt> options that are different. The values of these options must
- be legal target triples that your GCC compiler supports.</p>
-
- <p>The result of such a build is executables that are not runnable on
- on the build host (--build option) but can be executed on the compile host
- (--host option).</p>
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="objfiles">The Location of LLVM Object Files</a>
-</h3>
-
-<div>
-
-<p>The LLVM build system is capable of sharing a single LLVM source tree among
-several LLVM builds. Hence, it is possible to build LLVM for several different
-platforms or configurations using the same source tree.</p>
-
-<p>This is accomplished in the typical autoconf manner:</p>
-
-<ul>
- <li><p>Change directory to where the LLVM object files should live:</p>
-
- <div class="doc_code"><pre>% cd <i>OBJ_ROOT</i></pre></div></li>
-
- <li><p>Run the <tt>configure</tt> script found in the LLVM source
- directory:</p>
-
- <div class="doc_code"><pre>% <i>SRC_ROOT</i>/configure</pre></div></li>
-</ul>
-
-<p>The LLVM build will place files underneath <i>OBJ_ROOT</i> in directories
-named after the build type:</p>
-
-<dl>
- <dt>Debug Builds with assertions enabled (the default)
- <dd>
- <dl>
- <dt>Tools
- <dd><tt><i>OBJ_ROOT</i>/Debug+Asserts/bin</tt>
- <dt>Libraries
- <dd><tt><i>OBJ_ROOT</i>/Debug+Asserts/lib</tt>
- </dl>
- <br><br>
-
- <dt>Release Builds
- <dd>
- <dl>
- <dt>Tools
- <dd><tt><i>OBJ_ROOT</i>/Release/bin</tt>
- <dt>Libraries
- <dd><tt><i>OBJ_ROOT</i>/Release/lib</tt>
- </dl>
- <br><br>
-
- <dt>Profile Builds
- <dd>
- <dl>
- <dt>Tools
- <dd><tt><i>OBJ_ROOT</i>/Profile/bin</tt>
- <dt>Libraries
- <dd><tt><i>OBJ_ROOT</i>/Profile/lib</tt>
- </dl>
-</dl>
-
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="optionalconfig">Optional Configuration Items</a>
-</h3>
-
-<div>
-
-<p>
-If you're running on a Linux system that supports the "<a
-href="http://www.tat.physik.uni-tuebingen.de/~rguenth/linux/binfmt_misc.html">binfmt_misc</a>"
-module, and you have root access on the system, you can set your system up to
-execute LLVM bitcode files directly. To do this, use commands like this (the
-first command may not be required if you are already using the module):</p>
-
-<div class="doc_code">
-<pre>
-$ mount -t binfmt_misc none /proc/sys/fs/binfmt_misc
-$ echo ':llvm:M::BC::/path/to/lli:' &gt; /proc/sys/fs/binfmt_misc/register
-$ chmod u+x hello.bc (if needed)
-$ ./hello.bc
-</pre>
-</div>
-
-<p>
-This allows you to execute LLVM bitcode files directly. On Debian, you
-can also use this command instead of the 'echo' command above:
-</p>
-
-<div class="doc_code">
-<pre>
-$ sudo update-binfmts --install llvm /path/to/lli --magic 'BC'
-</pre>
-</div>
-
-</div>
-
-</div>
-
-<!-- *********************************************************************** -->
-<h2>
- <a name="layout">Program Layout</a>
-</h2>
-<!-- *********************************************************************** -->
-
-<div>
-
-<p>One useful source of information about the LLVM source base is the LLVM <a
-href="http://www.doxygen.org/">doxygen</a> documentation available at <tt><a
-href="http://llvm.org/doxygen/">http://llvm.org/doxygen/</a></tt>.
-The following is a brief introduction to code layout:</p>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="examples"><tt>llvm/examples</tt></a>
-</h3>
-
-<div>
- <p>This directory contains some simple examples of how to use the LLVM IR and
- JIT.</p>
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="include"><tt>llvm/include</tt></a>
-</h3>
-
-<div>
-
-<p>This directory contains public header files exported from the LLVM
-library. The three main subdirectories of this directory are:</p>
-
-<dl>
- <dt><tt><b>llvm/include/llvm</b></tt></dt>
- <dd>This directory contains all of the LLVM specific header files. This
- directory also has subdirectories for different portions of LLVM:
- <tt>Analysis</tt>, <tt>CodeGen</tt>, <tt>Target</tt>, <tt>Transforms</tt>,
- etc...</dd>
-
- <dt><tt><b>llvm/include/llvm/Support</b></tt></dt>
- <dd>This directory contains generic support libraries that are provided with
- LLVM but not necessarily specific to LLVM. For example, some C++ STL utilities
- and a Command Line option processing library store their header files here.
- </dd>
-
- <dt><tt><b>llvm/include/llvm/Config</b></tt></dt>
- <dd>This directory contains header files configured by the <tt>configure</tt>
- script. They wrap "standard" UNIX and C header files. Source code can
- include these header files which automatically take care of the conditional
- #includes that the <tt>configure</tt> script generates.</dd>
-</dl>
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="lib"><tt>llvm/lib</tt></a>
-</h3>
-
-<div>
-
-<p>This directory contains most of the source files of the LLVM system. In LLVM,
-almost all code exists in libraries, making it very easy to share code among the
-different <a href="#tools">tools</a>.</p>
-
-<dl>
- <dt><tt><b>llvm/lib/VMCore/</b></tt></dt>
- <dd> This directory holds the core LLVM source files that implement core
- classes like Instruction and BasicBlock.</dd>
-
- <dt><tt><b>llvm/lib/AsmParser/</b></tt></dt>
- <dd>This directory holds the source code for the LLVM assembly language parser
- library.</dd>
-
- <dt><tt><b>llvm/lib/BitCode/</b></tt></dt>
- <dd>This directory holds code for reading and write LLVM bitcode.</dd>
-
- <dt><tt><b>llvm/lib/Analysis/</b></tt><dd>This directory contains a variety of
- different program analyses, such as Dominator Information, Call Graphs,
- Induction Variables, Interval Identification, Natural Loop Identification,
- etc.</dd>
-
- <dt><tt><b>llvm/lib/Transforms/</b></tt></dt>
- <dd> This directory contains the source code for the LLVM to LLVM program
- transformations, such as Aggressive Dead Code Elimination, Sparse Conditional
- Constant Propagation, Inlining, Loop Invariant Code Motion, Dead Global
- Elimination, and many others.</dd>
-
- <dt><tt><b>llvm/lib/Target/</b></tt></dt>
- <dd> This directory contains files that describe various target architectures
- for code generation. For example, the <tt>llvm/lib/Target/X86</tt>
- directory holds the X86 machine description while
- <tt>llvm/lib/Target/ARM</tt> implements the ARM backend.</dd>
-
- <dt><tt><b>llvm/lib/CodeGen/</b></tt></dt>
- <dd> This directory contains the major parts of the code generator: Instruction
- Selector, Instruction Scheduling, and Register Allocation.</dd>
-
- <dt><tt><b>llvm/lib/MC/</b></tt></dt>
- <dd>(FIXME: T.B.D.)</dd>
-
- <!--FIXME: obsoleted -->
- <dt><tt><b>llvm/lib/Debugger/</b></tt></dt>
- <dd> This directory contains the source level debugger library that makes
- it possible to instrument LLVM programs so that a debugger could identify
- source code locations at which the program is executing.</dd>
-
- <dt><tt><b>llvm/lib/ExecutionEngine/</b></tt></dt>
- <dd> This directory contains libraries for executing LLVM bitcode directly
- at runtime in both interpreted and JIT compiled fashions.</dd>
-
- <dt><tt><b>llvm/lib/Support/</b></tt></dt>
- <dd> This directory contains the source code that corresponds to the header
- files located in <tt>llvm/include/ADT/</tt>
- and <tt>llvm/include/Support/</tt>.</dd>
-</dl>
-
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="projects"><tt>llvm/projects</tt></a>
-</h3>
-
-<div>
- <p>This directory contains projects that are not strictly part of LLVM but are
- shipped with LLVM. This is also the directory where you should create your own
- LLVM-based projects. See <tt>llvm/projects/sample</tt> for an example of how
- to set up your own project.</p>
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="runtime"><tt>llvm/runtime</tt></a>
-</h3>
-
-<div>
-
-<p>This directory contains libraries which are compiled into LLVM bitcode and
-used when linking programs with the Clang front end. Most of these libraries are
-skeleton versions of real libraries; for example, libc is a stripped down
-version of glibc.</p>
-
-<p>Unlike the rest of the LLVM suite, this directory needs the LLVM GCC front
-end to compile.</p>
-
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="test"><tt>llvm/test</tt></a>
-</h3>
-
-<div>
- <p>This directory contains feature and regression tests and other basic sanity
- checks on the LLVM infrastructure. These are intended to run quickly and cover
- a lot of territory without being exhaustive.</p>
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="test-suite"><tt>test-suite</tt></a>
-</h3>
-
-<div>
- <p>This is not a directory in the normal llvm module; it is a separate
- Subversion
- module that must be checked out (usually to <tt>projects/test-suite</tt>).
- This
- module contains a comprehensive correctness, performance, and benchmarking
- test
- suite for LLVM. It is a separate Subversion module because not every LLVM
- user is
- interested in downloading or building such a comprehensive test suite. For
- further details on this test suite, please see the
- <a href="TestingGuide.html">Testing Guide</a> document.</p>
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="tools"><tt>llvm/tools</tt></a>
-</h3>
-
-<div>
-
-<p>The <b>tools</b> directory contains the executables built out of the
-libraries above, which form the main part of the user interface. You can
-always get help for a tool by typing <tt>tool_name -help</tt>. The
-following is a brief introduction to the most important tools. More detailed
-information is in the <a href="CommandGuide/index.html">Command Guide</a>.</p>
-
-<dl>
-
- <dt><tt><b>bugpoint</b></tt></dt>
- <dd><tt>bugpoint</tt> is used to debug
- optimization passes or code generation backends by narrowing down the
- given test case to the minimum number of passes and/or instructions that
- still cause a problem, whether it is a crash or miscompilation. See <a
- href="HowToSubmitABug.html">HowToSubmitABug.html</a> for more information
- on using <tt>bugpoint</tt>.</dd>
-
- <dt><tt><b>llvm-ar</b></tt></dt>
- <dd>The archiver produces an archive containing
- the given LLVM bitcode files, optionally with an index for faster
- lookup.</dd>
-
- <dt><tt><b>llvm-as</b></tt></dt>
- <dd>The assembler transforms the human readable LLVM assembly to LLVM
- bitcode.</dd>
-
- <dt><tt><b>llvm-dis</b></tt></dt>
- <dd>The disassembler transforms the LLVM bitcode to human readable
- LLVM assembly.</dd>
-
- <dt><tt><b>llvm-link</b></tt></dt>
- <dd><tt>llvm-link</tt>, not surprisingly, links multiple LLVM modules into
- a single program.</dd>
-
- <dt><tt><b>lli</b></tt></dt>
- <dd><tt>lli</tt> is the LLVM interpreter, which
- can directly execute LLVM bitcode (although very slowly...). For architectures
- that support it (currently x86, Sparc, and PowerPC), by default, <tt>lli</tt>
- will function as a Just-In-Time compiler (if the functionality was compiled
- in), and will execute the code <i>much</i> faster than the interpreter.</dd>
-
- <dt><tt><b>llc</b></tt></dt>
- <dd> <tt>llc</tt> is the LLVM backend compiler, which
- translates LLVM bitcode to a native code assembly file or to C code (with
- the -march=c option).</dd>
-
- <dt><tt><b>llvm-gcc</b></tt></dt>
- <dd><tt>llvm-gcc</tt> is a GCC-based C frontend that has been retargeted to
- use LLVM as its backend instead of GCC's RTL backend. It can also emit LLVM
- bitcode or assembly (with the <tt>-emit-llvm</tt> option) instead of the
- usual machine code output. It works just like any other GCC compiler,
- taking the typical <tt>-c, -S, -E, -o</tt> options that are typically used.
- Additionally, the source code for <tt>llvm-gcc</tt> is available as a
- separate Subversion module.</dd>
-
- <dt><tt><b>opt</b></tt></dt>
- <dd><tt>opt</tt> reads LLVM bitcode, applies a series of LLVM to LLVM
- transformations (which are specified on the command line), and then outputs
- the resultant bitcode. The '<tt>opt -help</tt>' command is a good way to
- get a list of the program transformations available in LLVM.<br>
- <dd><tt>opt</tt> can also be used to run a specific analysis on an input
- LLVM bitcode file and print out the results. It is primarily useful for
- debugging analyses, or familiarizing yourself with what an analysis does.</dd>
-</dl>
-</div>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="utils"><tt>llvm/utils</tt></a>
-</h3>
-
-<div>
-
-<p>This directory contains utilities for working with LLVM source code, and some
-of the utilities are actually required as part of the build process because they
-are code generators for parts of LLVM infrastructure.</p>
-
-<dl>
- <dt><tt><b>codegen-diff</b></tt> <dd><tt>codegen-diff</tt> is a script
- that finds differences between code that LLC generates and code that LLI
- generates. This is a useful tool if you are debugging one of them,
- assuming that the other generates correct output. For the full user
- manual, run <tt>`perldoc codegen-diff'</tt>.<br><br>
-
- <dt><tt><b>emacs/</b></tt> <dd>The <tt>emacs</tt> directory contains
- syntax-highlighting files which will work with Emacs and XEmacs editors,
- providing syntax highlighting support for LLVM assembly files and TableGen
- description files. For information on how to use the syntax files, consult
- the <tt>README</tt> file in that directory.<br><br>
-
- <dt><tt><b>getsrcs.sh</b></tt> <dd>The <tt>getsrcs.sh</tt> script finds
- and outputs all non-generated source files, which is useful if one wishes
- to do a lot of development across directories and does not want to
- individually find each file. One way to use it is to run, for example:
- <tt>xemacs `utils/getsources.sh`</tt> from the top of your LLVM source
- tree.<br><br>
-
- <dt><tt><b>llvmgrep</b></tt></dt>
- <dd>This little tool performs an "egrep -H -n" on each source file in LLVM and
- passes to it a regular expression provided on <tt>llvmgrep</tt>'s command
- line. This is a very efficient way of searching the source base for a
- particular regular expression.</dd>
-
- <dt><tt><b>makellvm</b></tt> <dd>The <tt>makellvm</tt> script compiles all
- files in the current directory and then compiles and links the tool that
- is the first argument. For example, assuming you are in the directory
- <tt>llvm/lib/Target/Sparc</tt>, if <tt>makellvm</tt> is in your path,
- simply running <tt>makellvm llc</tt> will make a build of the current
- directory, switch to directory <tt>llvm/tools/llc</tt> and build it,
- causing a re-linking of LLC.<br><br>
-
- <dt><tt><b>TableGen/</b></tt> <dd>The <tt>TableGen</tt> directory contains
- the tool used to generate register descriptions, instruction set
- descriptions, and even assemblers from common TableGen description
- files.<br><br>
-
- <dt><tt><b>vim/</b></tt> <dd>The <tt>vim</tt> directory contains
- syntax-highlighting files which will work with the VIM editor, providing
- syntax highlighting support for LLVM assembly files and TableGen
- description files. For information on how to use the syntax files, consult
- the <tt>README</tt> file in that directory.<br><br>
-
-</dl>
-
-</div>
-
-</div>
-
-<!-- *********************************************************************** -->
-<h2>
- <a name="tutorial">An Example Using the LLVM Tool Chain</a>
-</h2>
-<!-- *********************************************************************** -->
-
-<div>
-<p>This section gives an example of using LLVM with the Clang front end.</p>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="tutorial4">Example with clang</a>
-</h3>
-
-<div>
-
-<ol>
- <li><p>First, create a simple C file, name it 'hello.c':</p>
-
-<div class="doc_code">
-<pre>
-#include &lt;stdio.h&gt;
-
-int main() {
- printf("hello world\n");
- return 0;
-}
-</pre></div></li>
-
- <li><p>Next, compile the C file into a native executable:</p>
-
- <div class="doc_code"><pre>% clang hello.c -o hello</pre></div>
-
- <p>Note that clang works just like GCC by default. The standard -S and
- -c arguments work as usual (producing a native .s or .o file,
- respectively).</p></li>
-
- <li><p>Next, compile the C file into a LLVM bitcode file:</p>
-
- <div class="doc_code">
- <pre>% clang -O3 -emit-llvm hello.c -c -o hello.bc</pre></div>
-
- <p>The -emit-llvm option can be used with the -S or -c options to emit an
- LLVM ".ll" or ".bc" file (respectively) for the code. This allows you
- to use the <a href="CommandGuide/index.html">standard LLVM tools</a> on
- the bitcode file.</p></li>
-
- <li><p>Run the program in both forms. To run the program, use:</p>
-
- <div class="doc_code"><pre>% ./hello</pre></div>
-
- <p>and</p>
-
- <div class="doc_code"><pre>% lli hello.bc</pre></div>
-
- <p>The second examples shows how to invoke the LLVM JIT, <a
- href="CommandGuide/html/lli.html">lli</a>.</p></li>
-
- <li><p>Use the <tt>llvm-dis</tt> utility to take a look at the LLVM assembly
- code:</p>
-
-<div class="doc_code">
-<pre>llvm-dis &lt; hello.bc | less</pre>
-</div></li>
-
- <li><p>Compile the program to native assembly using the LLC code
- generator:</p>
-
- <div class="doc_code"><pre>% llc hello.bc -o hello.s</pre></div></li>
-
- <li><p>Assemble the native assembly language file into a program:</p>
-
-<div class="doc_code">
-<pre>
-<b>Solaris:</b> % /opt/SUNWspro/bin/cc -xarch=v9 hello.s -o hello.native
-
-<b>Others:</b> % gcc hello.s -o hello.native
-</pre>
-</div></li>
-
- <li><p>Execute the native code program:</p>
-
- <div class="doc_code"><pre>% ./hello.native</pre></div>
-
- <p>Note that using clang to compile directly to native code (i.e. when
- the -emit-llvm option is not present) does steps 6/7/8 for you.</p>
- </li>
-
-</ol>
-
-</div>
-
-</div>
-
-<!-- *********************************************************************** -->
-<h2>
- <a name="problems">Common Problems</a>
-</h2>
-<!-- *********************************************************************** -->
-
-<div>
-
-<p>If you are having problems building or using LLVM, or if you have any other
-general questions about LLVM, please consult the <a href="FAQ.html">Frequently
-Asked Questions</a> page.</p>
-
-</div>
-
-<!-- *********************************************************************** -->
-<h2>
- <a name="links">Links</a>
-</h2>
-<!-- *********************************************************************** -->
-
-<div>
-
-<p>This document is just an <b>introduction</b> on how to use LLVM to do
-some simple things... there are many more interesting and complicated things
-that you can do that aren't documented here (but we'll gladly accept a patch
-if you want to write something up!). For more information about LLVM, check
-out:</p>
-
-<ul>
- <li><a href="http://llvm.org/">LLVM homepage</a></li>
- <li><a href="http://llvm.org/doxygen/">LLVM doxygen tree</a></li>
- <li><a href="http://llvm.org/docs/Projects.html">Starting a Project
- that Uses LLVM</a></li>
-</ul>
-
-</div>
-
-<!-- *********************************************************************** -->
-
-<hr>
-<address>
- <a href="http://jigsaw.w3.org/css-validator/check/referer"><img
- src="http://jigsaw.w3.org/css-validator/images/vcss-blue" alt="Valid CSS"></a>
- <a href="http://validator.w3.org/check/referer"><img
- src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
-
- <a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
- <a href="http://llvm.x10sys.com/rspencer/">Reid Spencer</a><br>
- <a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date$
-</address>
-</body>
-</html>
diff --git a/docs/GettingStarted.rst b/docs/GettingStarted.rst
new file mode 100644
index 0000000000..d78c78f1cc
--- /dev/null
+++ b/docs/GettingStarted.rst
@@ -0,0 +1,1304 @@
+.. _getting_started:
+
+====================================
+Getting Started with the LLVM System
+====================================
+
+Overview
+========
+
+Welcome to LLVM! In order to get started, you first need to know some basic
+information.
+
+First, LLVM comes in three pieces. The first piece is the LLVM suite. This
+contains all of the tools, libraries, and header files needed to use LLVM. It
+contains an assembler, disassembler, bitcode analyzer and bitcode optimizer. It
+also contains basic regression tests that can be used to test the LLVM tools and
+the Clang front end.
+
+The second piece is the `Clang <http://clang.llvm.org/>`_ front end. This
+component compiles C, C++, Objective C, and Objective C++ code into LLVM
+bitcode. Once compiled into LLVM bitcode, a program can be manipulated with the
+LLVM tools from the LLVM suite.
+
+There is a third, optional piece called Test Suite. It is a suite of programs
+with a testing harness that can be used to further test LLVM's functionality
+and performance.
+
+Getting Started Quickly (A Summary)
+===================================
+
+The LLVM Getting Started documentation may be out of date. So, the `Clang
+Getting Started <http://clang.llvm.org/get_started.html>`_ page might also be a
+good place to start.
+
+Here's the short story for getting up and running quickly with LLVM:
+
+#. Read the documentation.
+#. Read the documentation.
+#. Remember that you were warned twice about reading the documentation.
+#. Checkout LLVM:
+
+ * ``cd where-you-want-llvm-to-live``
+ * ``svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm``
+
+#. Checkout Clang:
+
+ * ``cd where-you-want-llvm-to-live``
+ * ``cd llvm/tools``
+ * ``svn co http://llvm.org/svn/llvm-project/cfe/trunk clang``
+
+#. Checkout Compiler-RT:
+
+ * ``cd where-you-want-llvm-to-live``
+ * ``cd llvm/projects``
+ * ``svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt``
+
+#. Get the Test Suite Source Code **[Optional]**
+
+ * ``cd where-you-want-llvm-to-live``
+ * ``cd llvm/projects``
+ * ``svn co http://llvm.org/svn/llvm-project/test-suite/trunk test-suite``
+
+#. Configure and build LLVM and Clang:
+
+ * ``cd where-you-want-to-build-llvm``
+ * ``mkdir build`` (for building without polluting the source dir)
+ * ``cd build``
+ * ``../llvm/configure [options]``
+ Some common options:
+
+ * ``--prefix=directory`` ---
+
+ Specify for *directory* the full pathname of where you want the LLVM
+ tools and libraries to be installed (default ``/usr/local``).
+
+ * ``--enable-optimized`` ---
+
+ Compile with optimizations enabled (default is NO).
+
+ * ``--enable-assertions`` ---
+
+ Compile with assertion checks enabled (default is YES).
+
+ * ``make [-j]`` --- The ``-j`` specifies the number of jobs (commands) to run
+ simultaneously. This builds both LLVM and Clang for Debug+Asserts mode.
+ The --enabled-optimized configure option is used to specify a Release
+ build.
+
+ * ``make check-all`` --- This run the regression tests to ensure everything
+ is in working order.
+
+ * ``make update`` --- This command is used to update all the svn repositories
+ at once, rather then having to ``cd`` into the individual repositories and
+ running ``svn update``.
+
+ * It is also possible to use CMake instead of the makefiles. With CMake it is
+ also possible to generate project files for several IDEs: Eclipse CDT4,
+ CodeBlocks, Qt-Creator (use the CodeBlocks generator), KDevelop3.
+
+ * If you get an "internal compiler error (ICE)" or test failures, see
+ `below`.
+
+Consult the `Getting Started with LLVM`_ section for detailed information on
+configuring and compiling LLVM. See `Setting Up Your Environment`_ for tips
+that simplify working with the Clang front end and LLVM tools. Go to `Program
+Layout`_ to learn about the layout of the source code tree.
+
+Requirements
+============
+
+Before you begin to use the LLVM system, review the requirements given below.
+This may save you some trouble by knowing ahead of time what hardware and
+software you will need.
+
+Hardware
+--------
+
+LLVM is known to work on the following platforms:
+
++-----------------+----------------------+-------------------------+
+|OS | Arch | Compilers |
++=================+======================+=========================+
+|AuroraUX | x86\ :sup:`1` | GCC |
++-----------------+----------------------+-------------------------+
+|Linux | x86\ :sup:`1` | GCC |
++-----------------+----------------------+-------------------------+
+|Linux | amd64 | GCC |
++-----------------+----------------------+-------------------------+
+|Solaris | V9 (Ultrasparc) | GCC |
++-----------------+----------------------+-------------------------+
+|FreeBSD | x86\ :sup:`1` | GCC |
++-----------------+----------------------+-------------------------+
+|FreeBSD | amd64 | GCC |
++-----------------+----------------------+-------------------------+
+|MacOS X\ :sup:`2`| PowerPC | GCC |
++-----------------+----------------------+-------------------------+
+|MacOS X\ :sup:`9`| x86 | GCC |
++-----------------+----------------------+-------------------------+
+|Cygwin/Win32 | x86\ :sup:`1, 8, 11` | GCC 3.4.X, binutils 2.20|
++-----------------+----------------------+-------------------------+
+
+LLVM has partial support for the following platforms:
+
++-------------------+----------------------+-------------------------------------------+
+|OS | Arch | Compilers |
++===================+======================+===========================================+
+| Windows | x86\ :sup:`1` | Visual Studio 2000 or higher\ :sup:`4,5` |
++-------------------+----------------------+-------------------------------------------+
+| AIX\ :sup:`3,4` | PowerPC | GCC |
++-------------------+----------------------+-------------------------------------------+
+| Linux\ :sup:`3,5` | PowerPC | GCC |
++-------------------+----------------------+-------------------------------------------+
+| Linux\ :sup:`7` | Alpha | GCC |
++-------------------+----------------------+-------------------------------------------+
+| Linux\ :sup:`7` | Itanium (IA-64) | GCC |
++-------------------+----------------------+-------------------------------------------+
+| HP-UX\ :sup:`7` | Itanium (IA-64) | HP aCC |
++-------------------+----------------------+-------------------------------------------+
+| Windows x64 | x86-64 | mingw-w64's GCC-4.5.x\ :sup:`12` |
++-------------------+----------------------+-------------------------------------------+
+
+.. note::
+
+ Code generation supported for Pentium processors and up
+
+ #. Code generation supported for Pentium processors and up
+ #. Code generation supported for 32-bit ABI only
+ #. No native code generation
+ #. Build is not complete: one or more tools do not link or function
+ #. The GCC-based C/C++ frontend does not build
+ #. The port is done using the MSYS shell.
+ #. Native code generation exists but is not complete.
+ #. Binutils 2.20 or later is required to build the assembler generated by LLVM properly.
+ #. Xcode 2.5 and gcc 4.0.1 (Apple Build 5370) will trip internal LLVM assert
+ messages when compiled for Release at optimization levels greater than 0
+ (i.e., ``-O1`` and higher). Add ``OPTIMIZE_OPTION="-O0"`` to the build
+ command line if compiling for LLVM Release or bootstrapping the LLVM
+ toolchain.
+ #. For MSYS/MinGW on Windows, be sure to install the MSYS version of the perl
+ package, and be sure it appears in your path before any Windows-based
+ versions such as Strawberry Perl and ActivePerl, as these have
+ Windows-specifics that will cause the build to fail.
+ #. To use LLVM modules on Win32-based system, you may configure LLVM
+ with ``--enable-shared``.
+
+ #. To compile SPU backend, you need to add ``LDFLAGS=-Wl,--stack,16777216`` to
+ configure.
+
+Note that you will need about 1-3 GB of space for a full LLVM build in Debug
+mode, depending on the system (it is so large because of all the debugging
+information and the fact that the libraries are statically linked into multiple
+tools). If you do not need many of the tools and you are space-conscious, you
+can pass ``ONLY_TOOLS="tools you need"`` to make. The Release build requires
+considerably less space.
+
+The LLVM suite *may* compile on other platforms, but it is not guaranteed to do
+so. If compilation is successful, the LLVM utilities should be able to
+assemble, disassemble, analyze, and optimize LLVM bitcode. Code generation
+should work as well, although the generated native code may not work on your
+platform.
+
+Software
+--------
+
+Compiling LLVM requires that you have several software packages installed. The
+table below lists those required packages. The Package column is the usual name
+for the software package that LLVM depends on. The Version column provides
+"known to work" versions of the package. The Notes column describes how LLVM
+uses the package and provides other details.
+
++--------------------------------------------------------------+-----------------+---------------------------------------------+
+| Package | Version | Notes |
++==============================================================+=================+=============================================+
+| `GNU Make <http://savannah.gnu.org/projects/make>`_ | 3.79, 3.79.1 | Makefile/build processor |
++--------------------------------------------------------------+-----------------+---------------------------------------------+
+| `GCC <http://gcc.gnu.org/>`_ | 3.4.2 | C/C++ compiler\ :sup:`1` |
++--------------------------------------------------------------+-----------------+---------------------------------------------+
+| `TeXinfo <http://www.gnu.org/software/texinfo/>`_ | 4.5 | For building the CFE |
++--------------------------------------------------------------+-----------------+---------------------------------------------+
+| `SVN <http://subversion.tigris.org/project_packages.html>`_ | >=1.3 | Subversion access to LLVM\ :sup:`2` |
++--------------------------------------------------------------+-----------------+---------------------------------------------+
+| `DejaGnu <http://savannah.gnu.org/projects/dejagnu>`_ | 1.4.2 | Automated test suite\ :sup:`3` |
++--------------------------------------------------------------+-----------------+---------------------------------------------+
+| `tcl <http://www.tcl.tk/software/tcltk/>`_ | 8.3, 8.4 | Automated test suite\ :sup:`3` |
++--------------------------------------------------------------+-----------------+---------------------------------------------+
+| `expect <http://expect.nist.gov/>`_ | 5.38.0 | Automated test suite\ :sup:`3` |
++--------------------------------------------------------------+-----------------+---------------------------------------------+
+| `perl <http://www.perl.com/download.csp>`_ | >=5.6.0 | Utilities |
++--------------------------------------------------------------+-----------------+---------------------------------------------+
+| `GNU M4 <http://savannah.gnu.org/projects/m4>`_ | 1.4 | Macro processor for configuration\ :sup:`4` |
++--------------------------------------------------------------+-----------------+---------------------------------------------+
+| `GNU Autoconf <http://www.gnu.org/software/autoconf/>`_ | 2.60 | Configuration script builder\ :sup:`4` |
++--------------------------------------------------------------+-----------------+---------------------------------------------+
+| `GNU Automake <http://www.gnu.org/software/automake/>`_ | 1.9.6 | aclocal macro generator\ :sup:`4` |
++--------------------------------------------------------------+-----------------+---------------------------------------------+
+| `libtool <http://savannah.gnu.org/projects/libtool>`_ | 1.5.22 | Shared library manager\ :sup:`4` |
++--------------------------------------------------------------+-----------------+---------------------------------------------+
+
+.. note::
+
+ #. Only the C and C++ languages are needed so there's no need to build the
+ other languages for LLVM's purposes. See `below` for specific version
+ info.
+ #. You only need Subversion if you intend to build from the latest LLVM
+ sources. If you're working from a release distribution, you don't need
+ Subversion.
+ #. Only needed if you want to run the automated test suite in the
+ ``llvm/test`` directory.
+ #. If you want to make changes to the configure scripts, you will need GNU
+ autoconf (2.60), and consequently, GNU M4 (version 1.4 or higher). You
+ will also need automake (1.9.6). We only use aclocal from that package.
+
+Additionally, your compilation host is expected to have the usual plethora of
+Unix utilities. Specifically:
+
+* **ar** --- archive library builder
+* **bzip2** --- bzip2 command for distribution generation
+* **bunzip2** --- bunzip2 command for distribution checking
+* **chmod** --- change permissions on a file
+* **cat** --- output concatenation utility
+* **cp** --- copy files
+* **date** --- print the current date/time
+* **echo** --- print to standard output
+* **egrep** --- extended regular expression search utility
+* **find** --- find files/dirs in a file system
+* **grep** --- regular expression search utility
+* **gzip** --- gzip command for distribution generation
+* **gunzip** --- gunzip command for distribution checking
+* **install** --- install directories/files
+* **mkdir** --- create a directory
+* **mv** --- move (rename) files
+* **ranlib** --- symbol table builder for archive libraries
+* **rm** --- remove (delete) files and directories
+* **sed** --- stream editor for transforming output
+* **sh** --- Bourne shell for make build scripts
+* **tar** --- tape archive for distribution generation
+* **test** --- test things in file system
+* **unzip** --- unzip command for distribution checking
+* **zip** --- zip command for distribution generation
+
+.. _below:
+.. _check here:
+
+Broken versions of GCC and other tools
+--------------------------------------
+
+LLVM is very demanding of the host C++ compiler, and as such tends to expose
+bugs in the compiler. In particular, several versions of GCC crash when trying
+to compile LLVM. We routinely use GCC 4.2 (and higher) or Clang. Other
+versions of GCC will probably work as well. GCC versions listed here are known
+to not work. If you are using one of these versions, please try to upgrade your
+GCC to something more recent. If you run into a problem with a version of GCC
+not listed here, please `let us know <mailto:llvmdev@cs.uiuc.edu>`_. Please use
+the "``gcc -v``" command to find out which version of GCC you are using.
+
+**GCC versions prior to 3.0**: GCC 2.96.x and before had several problems in the
+STL that effectively prevent it from compiling LLVM.
+
+**GCC 3.2.2 and 3.2.3**: These versions of GCC fails to compile LLVM with a
+bogus template error. This was fixed in later GCCs.
+
+**GCC 3.3.2**: This version of GCC suffered from a `serious bug
+<http://gcc.gnu.org/PR13392>`_ which causes it to crash in the
+"``convert_from_eh_region_ranges_1``" GCC function.
+
+**Cygwin GCC 3.3.3**: The version of GCC 3.3.3 commonly shipped with Cygwin does
+not work.
+
+**SuSE GCC 3.3.3**: The version of GCC 3.3.3 shipped with SuSE 9.1 (and possibly
+others) does not compile LLVM correctly (it appears that exception handling is
+broken in some cases). Please download the FSF 3.3.3 or upgrade to a newer
+version of GCC.
+
+**GCC 3.4.0 on linux/x86 (32-bit)**: GCC miscompiles portions of the code
+generator, causing an infinite loop in the llvm-gcc build when built with
+optimizations enabled (i.e. a release build).
+
+**GCC 3.4.2 on linux/x86 (32-bit)**: GCC miscompiles portions of the code
+generator at -O3, as with 3.4.0. However gcc 3.4.2 (unlike 3.4.0) correctly
+compiles LLVM at -O2. A work around is to build release LLVM builds with
+"``make ENABLE_OPTIMIZED=1 OPTIMIZE_OPTION=-O2 ...``"
+
+**GCC 3.4.x on X86-64/amd64**: GCC `miscompiles portions of LLVM
+<http://llvm.org/PR1056>`__.
+
+**GCC 3.4.4 (CodeSourcery ARM 2005q3-2)**: this compiler miscompiles LLVM when
+building with optimizations enabled. It appears to work with "``make
+ENABLE_OPTIMIZED=1 OPTIMIZE_OPTION=-O1``" or build a debug build.
+
+**IA-64 GCC 4.0.0**: The IA-64 version of GCC 4.0.0 is known to miscompile LLVM.
+
+**Apple Xcode 2.3**: GCC crashes when compiling LLVM at -O3 (which is the
+default with ENABLE_OPTIMIZED=1. To work around this, build with
+"``ENABLE_OPTIMIZED=1 OPTIMIZE_OPTION=-O2``".
+
+**GCC 4.1.1**: GCC fails to build LLVM with template concept check errors
+compiling some files. At the time of this writing, GCC mainline (4.2) did not
+share the problem.
+
+**GCC 4.1.1 on X86-64/amd64**: GCC `miscompiles portions of LLVM
+<http://llvm.org/PR1063>`__ when compiling llvm itself into 64-bit code. LLVM
+will appear to mostly work but will be buggy, e.g. failing portions of its
+testsuite.
+
+**GCC 4.1.2 on OpenSUSE**: Seg faults during libstdc++ build and on x86_64
+platforms compiling md5.c gets a mangled constant.
+
+**GCC 4.1.2 (20061115 (prerelease) (Debian 4.1.1-21)) on Debian**: Appears to
+miscompile parts of LLVM 2.4. One symptom is ValueSymbolTable complaining about
+symbols remaining in the table on destruction.
+
+**GCC 4.1.2 20071124 (Red Hat 4.1.2-42)**: Suffers from the same symptoms as the
+previous one. It appears to work with ENABLE_OPTIMIZED=0 (the default).
+
+**Cygwin GCC 4.3.2 20080827 (beta) 2**: Users `reported
+<http://llvm.org/PR4145>`_ various problems related with link errors when using
+this GCC version.
+
+**Debian GCC 4.3.2 on X86**: Crashes building some files in LLVM 2.6.
+
+**GCC 4.3.3 (Debian 4.3.3-10) on ARM**: Miscompiles parts of LLVM 2.6 when
+optimizations are turned on. The symptom is an infinite loop in
+``FoldingSetImpl::RemoveNode`` while running the code generator.
+
+**SUSE 11 GCC 4.3.4**: Miscompiles LLVM, causing crashes in ValueHandle logic.
+
+**GCC 4.3.5 and GCC 4.4.5 on ARM**: These can miscompile ``value >> 1`` even at
+``-O0``. A test failure in ``test/Assembler/alignstack.ll`` is one symptom of
+the problem.
+
+**GNU ld 2.16.X**. Some 2.16.X versions of the ld linker will produce very long
+warning messages complaining that some "``.gnu.linkonce.t.*``" symbol was
+defined in a discarded section. You can safely ignore these messages as they are
+erroneous and the linkage is correct. These messages disappear using ld 2.17.
+
+**GNU binutils 2.17**: Binutils 2.17 contains `a bug
+<http://sourceware.org/bugzilla/show_bug.cgi?id=3111>`__ which causes huge link
+times (minutes instead of seconds) when building LLVM. We recommend upgrading
+to a newer version (2.17.50.0.4 or later).
+
+**GNU Binutils 2.19.1 Gold**: This version of Gold contained `a bug
+<http://sourceware.org/bugzilla/show_bug.cgi?id=9836>`__ which causes
+intermittent failures when building LLVM with position independent code. The
+symptom is an error about cyclic dependencies. We recommend upgrading to a
+newer version of Gold.
+
+.. _Getting Started with LLVM:
+
+Getting Started with LLVM
+=========================
+
+The remainder of this guide is meant to get you up and running with LLVM and to
+give you some basic information about the LLVM environment.
+
+The later sections of this guide describe the `general layout`_ of the LLVM
+source tree, a `simple example`_ using the LLVM tool chain, and `links`_ to find
+more information about LLVM or to get help via e-mail.
+
+Terminology and Notation
+------------------------
+
+Throughout this manual, the following names are used to denote paths specific to
+the local system and working environment. *These are not environment variables
+you need to set but just strings used in the rest of this document below*. In
+any of the examples below, simply replace each of these names with the
+appropriate pathname on your local system. All these paths are absolute:
+
+``SRC_ROOT``
+
+ This is the top level directory of the LLVM source tree.
+
+``OBJ_ROOT``
+
+ This is the top level directory of the LLVM object tree (i.e. the tree where
+ object files and compiled programs will be placed. It can be the same as
+ SRC_ROOT).
+
+.. _Setting Up Your Environment:
+
+Setting Up Your Environment
+---------------------------
+
+In order to compile and use LLVM, you may need to set some environment
+variables.
+
+``LLVM_LIB_SEARCH_PATH=/path/to/your/bitcode/libs``
+
+ [Optional] This environment variable helps LLVM linking tools find the
+ locations of your bitcode libraries. It is provided only as a convenience
+ since you can specify the paths using the -L options of the tools and the
+ C/C++ front-end will automatically use the bitcode files installed in its
+ ``lib`` directory.
+
+Unpacking the LLVM Archives
+---------------------------
+
+If you have the LLVM distribution, you will need to unpack it before you can
+begin to compile it. LLVM is distributed as a set of two files: the LLVM suite
+and the LLVM GCC front end compiled for your platform. There is an additional
+test suite that is optional. Each file is a TAR archive that is compressed with
+the gzip program.
+
+The files are as follows, with *x.y* marking the version number:
+
+``llvm-x.y.tar.gz``
+
+ Source release for the LLVM libraries and tools.
+
+``llvm-test-x.y.tar.gz``
+
+ Source release for the LLVM test-suite.
+
+``llvm-gcc-4.2-x.y.source.tar.gz``
+
+ Source release of the llvm-gcc-4.2 front end. See README.LLVM in the root
+ directory for build instructions.
+
+``llvm-gcc-4.2-x.y-platform.tar.gz``
+
+ Binary release of the llvm-gcc-4.2 front end for a specific platform.
+
+Checkout LLVM from Subversion
+-----------------------------
+
+If you have access to our Subversion repository, you can get a fresh copy of the
+entire source code. All you need to do is check it out from Subversion as
+follows:
+
+* ``cd where-you-want-llvm-to-live``
+* Read-Only: ``svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm``
+* Read-Write:``svn co https://user@llvm.org/svn/llvm-project/llvm/trunk llvm``
+
+This will create an '``llvm``' directory in the current directory and fully
+populate it with the LLVM source code, Makefiles, test directories, and local
+copies of documentation files.
+
+If you want to get a specific release (as opposed to the most recent revision),
+you can checkout it from the '``tags``' directory (instead of '``trunk``'). The
+following releases are located in the following subdirectories of the '``tags``'
+directory:
+
+* Release 3.1: **RELEASE_31/final**
+* Release 3.0: **RELEASE_30/final**
+* Release 2.9: **RELEASE_29/final**
+* Release 2.8: **RELEASE_28**
+* Release 2.7: **RELEASE_27**
+* Release 2.6: **RELEASE_26**
+* Release 2.5: **RELEASE_25**
+* Release 2.4: **RELEASE_24**
+* Release 2.3: **RELEASE_23**
+* Release 2.2: **RELEASE_22**
+* Release 2.1: **RELEASE_21**
+* Release 2.0: **RELEASE_20**
+* Release 1.9: **RELEASE_19**
+* Release 1.8: **RELEASE_18**
+* Release 1.7: **RELEASE_17**
+* Release 1.6: **RELEASE_16**
+* Release 1.5: **RELEASE_15**
+* Release 1.4: **RELEASE_14**
+* Release 1.3: **RELEASE_13**
+* Release 1.2: **RELEASE_12**
+* Release 1.1: **RELEASE_11**
+* Release 1.0: **RELEASE_1**
+
+If you would like to get the LLVM test suite (a separate package as of 1.4), you
+get it from the Subversion repository:
+
+.. code:: bash
+
+ % cd llvm/projects
+ % svn co http://llvm.org/svn/llvm-project/test-suite/trunk test-suite
+
+By placing it in the ``llvm/projects``, it will be automatically configured by
+the LLVM configure script as well as automatically updated when you run ``svn
+update``.
+
+GIT mirror
+----------
+
+GIT mirrors are available for a number of LLVM subprojects. These mirrors sync
+automatically with each Subversion commit and contain all necessary git-svn
+marks (so, you can recreate git-svn metadata locally). Note that right now
+mirrors reflect only ``trunk`` for each project. You can do the read-only GIT
+clone of LLVM via:
+
+.. code:: bash
+
+ % git clone http://llvm.org/git/llvm.git
+
+If you want to check out clang too, run:
+
+.. code:: bash
+
+ % git clone http://llvm.org/git/llvm.git
+ % cd llvm/tools
+ % git clone http://llvm.org/git/clang.git
+
+Since the upstream repository is in Subversion, you should use ``git
+pull --rebase`` instead of ``git pull`` to avoid generating a non-linear history
+in your clone. To configure ``git pull`` to pass ``--rebase`` by default on the
+master branch, run the following command:
+
+.. code:: bash
+
+ % git config branch.master.rebase true
+
+Sending patches with Git
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Please read `Developer Policy <DeveloperPolicy.html#patches>`_, too.
+
+Assume ``master`` points the upstream and ``mybranch`` points your working
+branch, and ``mybranch`` is rebased onto ``master``. At first you may check
+sanity of whitespaces:
+
+.. code:: bash
+
+ % git diff --check master..mybranch
+
+The easiest way to generate a patch is as below:
+
+.. code:: bash
+
+ % git diff master..mybranch > /path/to/mybranch.diff
+
+It is a little different from svn-generated diff. git-diff-generated diff has
+prefixes like ``a/`` and ``b/``. Don't worry, most developers might know it
+could be accepted with ``patch -p1 -N``.
+
+But you may generate patchset with git-format-patch. It generates by-each-commit
+patchset. To generate patch files to attach to your article:
+
+.. code:: bash
+
+ % git format-patch --no-attach master..mybranch -o /path/to/your/patchset
+
+If you would like to send patches directly, you may use git-send-email or
+git-imap-send. Here is an example to generate the patchset in Gmail's [Drafts].
+
+.. code:: bash
+
+ % git format-patch --attach master..mybranch --stdout | git imap-send
+
+Then, your .git/config should have [imap] sections.
+
+.. code:: bash
+
+ [imap]
+ host = imaps://imap.gmail.com
+ user = your.gmail.account@gmail.com
+ pass = himitsu!
+ port = 993
+ sslverify = false
+ ; in English
+ folder = "[Gmail]/Drafts"
+ ; example for Japanese, "Modified UTF-7" encoded.
+ folder = "[Gmail]/&amp;Tgtm+DBN-"
+ ; example for Traditional Chinese
+ folder = "[Gmail]/&amp;g0l6Pw-"
+
+For developers to work with git-svn
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To set up clone from which you can submit code using ``git-svn``, run:
+
+.. code:: bash
+
+ % git clone http://llvm.org/git/llvm.git
+ % cd llvm
+ % git svn init https://llvm.org/svn/llvm-project/llvm/trunk --username=<username>
+ % git config svn-remote.svn.fetch :refs/remotes/origin/master
+ % git svn rebase -l # -l avoids fetching ahead of the git mirror.
+
+ # If you have clang too:
+ % cd tools
+ % git clone http://llvm.org/git/clang.git
+ % cd clang
+ % git svn init https://llvm.org/svn/llvm-project/cfe/trunk --username=<username>
+ % git config svn-remote.svn.fetch :refs/remotes/origin/master
+ % git svn rebase -l
+
+To update this clone without generating git-svn tags that conflict with the
+upstream git repo, run:
+
+.. code:: bash
+
+ % git fetch && (cd tools/clang && git fetch) # Get matching revisions of both trees.
+ % git checkout master
+ % git svn rebase -l
+ % (cd tools/clang &&
+ git checkout master &&
+ git svn rebase -l)
+
+This leaves your working directories on their master branches, so you'll need to
+``checkout`` each working branch individually and ``rebase`` it on top of its
+parent branch. (Note: This script is intended for relative newbies to git. If
+you have more experience, you can likely improve on it.)
+
+The git-svn metadata can get out of sync after you mess around with branches and
+``dcommit``. When that happens, ``git svn dcommit`` stops working, complaining
+about files with uncommitted changes. The fix is to rebuild the metadata:
+
+.. code:: bash
+
+ % rm -rf .git/svn
+ % git svn rebase -l
+
+Local LLVM Configuration
+------------------------
+
+Once checked out from the Subversion repository, the LLVM suite source code must
+be configured via the ``configure`` script. This script sets variables in the
+various ``*.in`` files, most notably ``llvm/Makefile.config`` and
+``llvm/include/Config/config.h``. It also populates *OBJ_ROOT* with the
+Makefiles needed to begin building LLVM.
+
+The following environment variables are used by the ``configure`` script to
+configure the build system:
+
++------------+-----------------------------------------------------------+
+| Variable | Purpose |
++============+===========================================================+
+| CC | Tells ``configure`` which C compiler to use. By default, |
+| | ``configure`` will look for the first GCC C compiler in |
+| | ``PATH``. Use this variable to override ``configure``\'s |
+| | default behavior. |
++------------+-----------------------------------------------------------+
+| CXX | Tells ``configure`` which C++ compiler to use. By |
+| | default, ``configure`` will look for the first GCC C++ |
+| | compiler in ``PATH``. Use this variable to override |
+| | ``configure``'s default behavior. |
++------------+-----------------------------------------------------------+
+
+The following options can be used to set or enable LLVM specific options:
+
+``--enable-optimized``
+
+ Enables optimized compilation (debugging symbols are removed and GCC
+ optimization flags are enabled). Note that this is the default setting if you
+ are using the LLVM distribution. The default behavior of an Subversion
+ checkout is to use an unoptimized build (also known as a debug build).
+
+``--enable-debug-runtime``
+
+ Enables debug symbols in the runtime libraries. The default is to strip debug
+ symbols from the runtime libraries.
+
+``--enable-jit``
+
+ Compile the Just In Time (JIT) compiler functionality. This is not available
+ on all platforms. The default is dependent on platform, so it is best to
+ explicitly enable it if you want it.
+
+``--enable-targets=target-option``
+
+ Controls which targets will be built and linked into llc. The default value
+ for ``target_options`` is "all" which builds and links all available targets.
+ The value "host-only" can be specified to build only a native compiler (no
+ cross-compiler targets available). The "native" target is selected as the
+ target of the build host. You can also specify a comma separated list of
+ target names that you want available in llc. The target names use all lower
+ case. The current set of targets is:
+
+ ``arm, cpp, hexagon, mblaze, mips, mipsel, msp430, powerpc, ptx, sparc, spu,
+ x86, x86_64, xcore``.
+
+``--enable-doxygen``
+
+ Look for the doxygen program and enable construction of doxygen based
+ documentation from the source code. This is disabled by default because
+ generating the documentation can take a long time and producess 100s of
+ megabytes of output.
+
+``--with-udis86``
+
+ LLVM can use external disassembler library for various purposes (now it's used
+ only for examining code produced by JIT). This option will enable usage of
+ `udis86 <http://udis86.sourceforge.net/>`_ x86 (both 32 and 64 bits)
+ disassembler library.
+
+To configure LLVM, follow these steps:
+
+#. Change directory into the object root directory:
+
+ .. code:: bash
+
+ % cd OBJ_ROOT
+
+#. Run the ``configure`` script located in the LLVM source tree:
+
+ .. code:: bash
+
+ % SRC_ROOT/configure --prefix=/install/path [other options]
+
+Compiling the LLVM Suite Source Code
+------------------------------------
+
+Once you have configured LLVM, you can build it. There are three types of
+builds:
+
+Debug Builds
+
+ These builds are the default when one is using an Subversion checkout and
+ types ``gmake`` (unless the ``--enable-optimized`` option was used during
+ configuration). The build system will compile the tools and libraries with
+ debugging information. To get a Debug Build using the LLVM distribution the
+ ``--disable-optimized`` option must be passed to ``configure``.
+
+Release (Optimized) Builds
+
+ These builds are enabled with the ``--enable-optimized`` option to
+ ``configure`` or by specifying ``ENABLE_OPTIMIZED=1`` on the ``gmake`` command
+ line. For these builds, the build system will compile the tools and libraries
+ with GCC optimizations enabled and strip debugging information from the
+ libraries and executables it generates. Note that Release Builds are default
+ when using an LLVM distribution.
+
+Profile Builds
+
+ These builds are for use with profiling. They compile profiling information
+ into the code for use with programs like ``gprof``. Profile builds must be
+ started by specifying ``ENABLE_PROFILING=1`` on the ``gmake`` command line.
+
+Once you have LLVM configured, you can build it by entering the *OBJ_ROOT*
+directory and issuing the following command:
+
+.. code:: bash
+
+ % gmake
+
+If the build fails, please `check here`_ to see if you are using a version of
+GCC that is known not to compile LLVM.
+
+If you have multiple processors in your machine, you may wish to use some of the
+parallel build options provided by GNU Make. For example, you could use the
+command:
+
+.. code:: bash
+
+ % gmake -j2
+
+There are several special targets which are useful when working with the LLVM
+source code:
+
+``gmake clean``
+
+ Removes all files generated by the build. This includes object files,
+ generated C/C++ files, libraries, and executables.
+
+``gmake dist-clean``
+
+ Removes everything that ``gmake clean`` does, but also removes files generated
+ by ``configure``. It attempts to return the source tree to the original state
+ in which it was shipped.
+
+``gmake install``
+
+ Installs LLVM header files, libraries, tools, and documentation in a hierarchy
+ under ``$PREFIX``, specified with ``./configure --prefix=[dir]``, which
+ defaults to ``/usr/local``.
+
+``gmake -C runtime install-bytecode``
+
+ Assuming you built LLVM into $OBJDIR, when this command is run, it will
+ install bitcode libraries into the GCC front end's bitcode library directory.
+ If you need to update your bitcode libraries, this is the target to use once
+ you've built them.
+
+Please see the `Makefile Guide <MakefileGuide.html>`_ for further details on
+these ``make`` targets and descriptions of other targets available.
+
+It is also possible to override default values from ``configure`` by declaring
+variables on the command line. The following are some examples:
+
+``gmake ENABLE_OPTIMIZED=1``
+
+ Perform a Release (Optimized) build.
+
+``gmake ENABLE_OPTIMIZED=1 DISABLE_ASSERTIONS=1``
+
+ Perform a Release (Optimized) build without assertions enabled.
+
+``gmake ENABLE_OPTIMIZED=0``
+
+ Perform a Debug build.
+
+``gmake ENABLE_PROFILING=1``
+
+ Perform a Profiling build.
+
+``gmake VERBOSE=1``
+
+ Print what ``gmake`` is doing on standard output.
+
+``gmake TOOL_VERBOSE=1``
+
+ Ask each tool invoked by the makefiles to print out what it is doing on
+ the standard output. This also implies ``VERBOSE=1``.
+
+Every directory in the LLVM object tree includes a ``Makefile`` to build it and
+any subdirectories that it contains. Entering any directory inside the LLVM
+object tree and typing ``gmake`` should rebuild anything in or below that
+directory that is out of date.
+
+Cross-Compiling LLVM
+--------------------
+
+It is possible to cross-compile LLVM itself. That is, you can create LLVM
+executables and libraries to be hosted on a platform different from the platform
+where they are build (a Canadian Cross build). To configure a cross-compile,
+supply the configure script with ``--build`` and ``--host`` options that are
+different. The values of these options must be legal target triples that your
+GCC compiler supports.
+
+The result of such a build is executables that are not runnable on on the build
+host (--build option) but can be executed on the compile host (--host option).
+
+The Location of LLVM Object Files
+---------------------------------
+
+The LLVM build system is capable of sharing a single LLVM source tree among
+several LLVM builds. Hence, it is possible to build LLVM for several different
+platforms or configurations using the same source tree.
+
+This is accomplished in the typical autoconf manner:
+
+* Change directory to where the LLVM object files should live:
+
+ .. code:: bash
+
+ % cd OBJ_ROOT
+
+* Run the ``configure`` script found in the LLVM source directory:
+
+ .. code:: bash
+
+ % SRC_ROOT/configure
+
+The LLVM build will place files underneath *OBJ_ROOT* in directories named after
+the build type:
+
+Debug Builds with assertions enabled (the default)
+
+ Tools
+
+ ``OBJ_ROOT/Debug+Asserts/bin``
+
+ Libraries
+
+ ``OBJ_ROOT/Debug+Asserts/lib``
+
+Release Builds
+
+ Tools
+
+ ``OBJ_ROOT/Release/bin``
+
+ Libraries
+
+ ``OBJ_ROOT/Release/lib``
+
+Profile Builds
+
+ Tools
+
+ ``OBJ_ROOT/Profile/bin``
+
+ Libraries
+
+ ``OBJ_ROOT/Profile/lib``
+
+Optional Configuration Items
+----------------------------
+
+If you're running on a Linux system that supports the `binfmt_misc
+<http://www.tat.physik.uni-tuebingen.de/~rguenth/linux/binfmt_misc.html>`_
+module, and you have root access on the system, you can set your system up to
+execute LLVM bitcode files directly. To do this, use commands like this (the
+first command may not be required if you are already using the module):
+
+.. code:: bash
+
+ % mount -t binfmt_misc none /proc/sys/fs/binfmt_misc
+ % echo ':llvm:M::BC::/path/to/lli:' > /proc/sys/fs/binfmt_misc/register
+ % chmod u+x hello.bc (if needed)
+ % ./hello.bc
+
+This allows you to execute LLVM bitcode files directly. On Debian, you can also
+use this command instead of the 'echo' command above:
+
+.. code:: bash
+
+ % sudo update-binfmts --install llvm /path/to/lli --magic 'BC'
+
+.. _Program Layout:
+.. _general layout:
+
+Program Layout
+==============
+
+One useful source of information about the LLVM source base is the LLVM `doxygen
+<http://www.doxygen.org/>`_ documentation available at
+`<http://llvm.org/doxygen/>`_. The following is a brief introduction to code
+layout:
+
+``llvm/examples``
+-----------------
+
+This directory contains some simple examples of how to use the LLVM IR and JIT.
+
+``llvm/include``
+----------------
+
+This directory contains public header files exported from the LLVM library. The
+three main subdirectories of this directory are:
+
+``llvm/include/llvm``
+
+ This directory contains all of the LLVM specific header files. This directory
+ also has subdirectories for different portions of LLVM: ``Analysis``,
+ ``CodeGen``, ``Target``, ``Transforms``, etc...
+
+``llvm/include/llvm/Support``
+
+ This directory contains generic support libraries that are provided with LLVM
+ but not necessarily specific to LLVM. For example, some C++ STL utilities and
+ a Command Line option processing library store their header files here.
+
+``llvm/include/llvm/Config``
+
+ This directory contains header files configured by the ``configure`` script.
+ They wrap "standard" UNIX and C header files. Source code can include these
+ header files which automatically take care of the conditional #includes that
+ the ``configure`` script generates.
+
+``llvm/lib``
+------------
+
+This directory contains most of the source files of the LLVM system. In LLVM,
+almost all code exists in libraries, making it very easy to share code among the
+different `tools`_.
+
+``llvm/lib/VMCore/``
+
+ This directory holds the core LLVM source files that implement core classes
+ like Instruction and BasicBlock.
+
+``llvm/lib/AsmParser/``
+
+ This directory holds the source code for the LLVM assembly language parser
+ library.
+
+``llvm/lib/BitCode/``
+
+ This directory holds code for reading and write LLVM bitcode.
+
+``llvm/lib/Analysis/``
+
+ This directory contains a variety of different program analyses, such as
+ Dominator Information, Call Graphs, Induction Variables, Interval
+ Identification, Natural Loop Identification, etc.
+
+``llvm/lib/Transforms/``
+
+ This directory contains the source code for the LLVM to LLVM program
+ transformations, such as Aggressive Dead Code Elimination, Sparse Conditional
+ Constant Propagation, Inlining, Loop Invariant Code Motion, Dead Global
+ Elimination, and many others.
+
+``llvm/lib/Target/``
+
+ This directory contains files that describe various target architectures for
+ code generation. For example, the ``llvm/lib/Target/X86`` directory holds the
+ X86 machine description while ``llvm/lib/Target/ARM`` implements the ARM
+ backend.
+
+``llvm/lib/CodeGen/``
+
+ This directory contains the major parts of the code generator: Instruction
+ Selector, Instruction Scheduling, and Register Allocation.
+
+``llvm/lib/MC/``
+
+ (FIXME: T.B.D.)
+
+``llvm/lib/Debugger/``
+
+ This directory contains the source level debugger library that makes it
+ possible to instrument LLVM programs so that a debugger could identify source
+ code locations at which the program is executing.
+
+``llvm/lib/ExecutionEngine/``
+
+ This directory contains libraries for executing LLVM bitcode directly at
+ runtime in both interpreted and JIT compiled fashions.
+
+``llvm/lib/Support/``
+
+ This directory contains the source code that corresponds to the header files
+ located in ``llvm/include/ADT/`` and ``llvm/include/Support/``.
+
+``llvm/projects``
+-----------------
+
+This directory contains projects that are not strictly part of LLVM but are
+shipped with LLVM. This is also the directory where you should create your own
+LLVM-based projects. See ``llvm/projects/sample`` for an example of how to set
+up your own project.
+
+``llvm/runtime``
+----------------
+
+This directory contains libraries which are compiled into LLVM bitcode and used
+when linking programs with the Clang front end. Most of these libraries are
+skeleton versions of real libraries; for example, libc is a stripped down
+version of glibc.
+
+Unlike the rest of the LLVM suite, this directory needs the LLVM GCC front end
+to compile.
+
+``llvm/test``
+-------------
+
+This directory contains feature and regression tests and other basic sanity
+checks on the LLVM infrastructure. These are intended to run quickly and cover a
+lot of territory without being exhaustive.
+
+``test-suite``
+--------------
+
+This is not a directory in the normal llvm module; it is a separate Subversion
+module that must be checked out (usually to ``projects/test-suite``). This
+module contains a comprehensive correctness, performance, and benchmarking test
+suite for LLVM. It is a separate Subversion module because not every LLVM user
+is interested in downloading or building such a comprehensive test suite. For
+further details on this test suite, please see the `Testing
+Guide <TestingGuide.html>`_ document.
+
+.. _tools:
+
+``llvm/tools``
+--------------
+
+The **tools** directory contains the executables built out of the libraries
+above, which form the main part of the user interface. You can always get help
+for a tool by typing ``tool_name -help``. The following is a brief introduction
+to the most important tools. More detailed information is in
+the `Command Guide <CommandGuide/index.html>`_.
+
+``bugpoint``
+
+ ``bugpoint`` is used to debug optimization passes or code generation backends
+ by narrowing down the given test case to the minimum number of passes and/or
+ instructions that still cause a problem, whether it is a crash or
+ miscompilation. See `<HowToSubmitABug.html>`_ for more information on using
+ ``bugpoint``.
+
+``llvm-ar``
+
+ The archiver produces an archive containing the given LLVM bitcode files,
+ optionally with an index for faster lookup.
+
+``llvm-as``
+
+ The assembler transforms the human readable LLVM assembly to LLVM bitcode.
+
+``llvm-dis``
+
+ The disassembler transforms the LLVM bitcode to human readable LLVM assembly.
+
+``llvm-link``
+
+ ``llvm-link``, not surprisingly, links multiple LLVM modules into a single
+ program.
+
+``lli``
+
+ ``lli`` is the LLVM interpreter, which can directly execute LLVM bitcode
+ (although very slowly...). For architectures that support it (currently x86,
+ Sparc, and PowerPC), by default, ``lli`` will function as a Just-In-Time
+ compiler (if the functionality was compiled in), and will execute the code
+ *much* faster than the interpreter.
+
+``llc``
+
+ ``llc`` is the LLVM backend compiler, which translates LLVM bitcode to a
+ native code assembly file or to C code (with the ``-march=c`` option).
+
+``opt``
+
+ ``opt`` reads LLVM bitcode, applies a series of LLVM to LLVM transformations
+ (which are specified on the command line), and then outputs the resultant
+ bitcode. The '``opt -help``' command is a good way to get a list of the
+ program transformations available in LLVM.
+
+ ``opt`` can also be used to run a specific analysis on an input LLVM bitcode
+ file and print out the results. It is primarily useful for debugging
+ analyses, or familiarizing yourself with what an analysis does.
+
+``llvm/utils``
+--------------
+
+This directory contains utilities for working with LLVM source code, and some of
+the utilities are actually required as part of the build process because they
+are code generators for parts of LLVM infrastructure.
+
+
+``codegen-diff``
+
+ ``codegen-diff`` is a script that finds differences between code that LLC
+ generates and code that LLI generates. This is a useful tool if you are
+ debugging one of them, assuming that the other generates correct output. For
+ the full user manual, run ```perldoc codegen-diff'``.
+
+``emacs/``
+
+ The ``emacs`` directory contains syntax-highlighting files which will work
+ with Emacs and XEmacs editors, providing syntax highlighting support for LLVM
+ assembly files and TableGen description files. For information on how to use
+ the syntax files, consult the ``README`` file in that directory.
+
+``getsrcs.sh``
+
+ The ``getsrcs.sh`` script finds and outputs all non-generated source files,
+ which is useful if one wishes to do a lot of development across directories
+ and does not want to individually find each file. One way to use it is to run,
+ for example: ``xemacs `utils/getsources.sh``` from the top of your LLVM source
+ tree.
+
+``llvmgrep``
+
+ This little tool performs an ``egrep -H -n`` on each source file in LLVM and
+ passes to it a regular expression provided on ``llvmgrep``'s command
+ line. This is a very efficient way of searching the source base for a
+ particular regular expression.
+
+``makellvm``
+
+ The ``makellvm`` script compiles all files in the current directory and then
+ compiles and links the tool that is the first argument. For example, assuming
+ you are in the directory ``llvm/lib/Target/Sparc``, if ``makellvm`` is in your
+ path, simply running ``makellvm llc`` will make a build of the current
+ directory, switch to directory ``llvm/tools/llc`` and build it, causing a
+ re-linking of LLC.
+
+``TableGen/``
+
+ The ``TableGen`` directory contains the tool used to generate register
+ descriptions, instruction set descriptions, and even assemblers from common
+ TableGen description files.
+
+``vim/``
+
+ The ``vim`` directory contains syntax-highlighting files which will work with
+ the VIM editor, providing syntax highlighting support for LLVM assembly files
+ and TableGen description files. For information on how to use the syntax
+ files, consult the ``README`` file in that directory.
+
+.. _simple example:
+
+An Example Using the LLVM Tool Chain
+====================================
+
+This section gives an example of using LLVM with the Clang front end.
+
+Example with clang
+------------------
+
+#. First, create a simple C file, name it 'hello.c':
+
+ .. code:: c
+
+ #include <stdio.h>
+
+ int main() {
+ printf("hello world\n");
+ return 0;
+ }
+
+#. Next, compile the C file into a native executable:
+
+ .. code:: bash
+
+ % clang hello.c -o hello
+
+ .. note::
+
+ Clang works just like GCC by default. The standard -S and -c arguments
+ work as usual (producing a native .s or .o file, respectively).
+
+#. Next, compile the C file into a LLVM bitcode file:
+
+ .. code:: bash
+
+ % clang -O3 -emit-llvm hello.c -c -o hello.bc
+
+ The -emit-llvm option can be used with the -S or -c options to emit an LLVM
+ ``.ll`` or ``.bc`` file (respectively) for the code. This allows you to use
+ the `standard LLVM tools <CommandGuide/index.html>`_ on the bitcode file.
+
+#. Run the program in both forms. To run the program, use:
+
+ .. code:: bash
+
+ % ./hello
+
+ and
+
+ .. code:: bash
+
+ % lli hello.bc
+
+ The second examples shows how to invoke the LLVM JIT, `lli
+ <CommandGuide/html/lli.html>`_.
+
+#. Use the ``llvm-dis`` utility to take a look at the LLVM assembly code:
+
+ .. code:: bash
+
+ % llvm-dis < hello.bc | less
+
+#. Compile the program to native assembly using the LLC code generator:
+
+ .. code:: bash
+
+ % llc hello.bc -o hello.s
+
+#. Assemble the native assembly language file into a program:
+
+ .. code:: bash
+
+ **Solaris:** % /opt/SUNWspro/bin/cc -xarch=v9 hello.s -o hello.native
+
+ **Others:** % gcc hello.s -o hello.native
+
+#. Execute the native code program:
+
+ .. code:: bash
+
+ % ./hello.native
+
+ Note that using clang to compile directly to native code (i.e. when the
+ ``-emit-llvm`` option is not present) does steps 6/7/8 for you.
+
+Common Problems
+===============
+
+If you are having problems building or using LLVM, or if you have any other
+general questions about LLVM, please consult the `Frequently Asked
+Questions <FAQ.html>`_ page.
+
+.. _links:
+
+Links
+=====
+
+This document is just an **introduction** on how to use LLVM to do some simple
+things... there are many more interesting and complicated things that you can do
+that aren't documented here (but we'll gladly accept a patch if you want to
+write something up!). For more information about LLVM, check out:
+
+* `LLVM Homepage <http://llvm.org/>`_
+* `LLVM Doxygen Tree <http://llvm.org/doxygen/>`_
+* `Starting a Project that Uses LLVM <http://llvm.org/docs/Projects.html>`_
diff --git a/docs/GoldPlugin.html b/docs/GoldPlugin.html
deleted file mode 100644
index 1e99a5a3d6..0000000000
--- a/docs/GoldPlugin.html
+++ /dev/null
@@ -1,227 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
- "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <title>LLVM gold plugin</title>
- <link rel="stylesheet" href="_static/llvm.css" type="text/css">
-</head>
-<body>
-
-<h1>LLVM gold plugin</h1>
-<ol>
- <li><a href="#introduction">Introduction</a></li>
- <li><a href="#build">How to build it</a></li>
- <li><a href="#usage">Usage</a>
- <ul>
- <li><a href="#example1">Example of link time optimization</a></li>
- <li><a href="#lto_autotools">Quickstart for using LTO with autotooled projects</a></li>
- </ul></li>
- <li><a href="#licensing">Licensing</a></li>
-</ol>
-<div class="doc_author">Written by Nick Lewycky</div>
-
-<!--=========================================================================-->
-<h2><a name="introduction">Introduction</a></h2>
-<!--=========================================================================-->
-<div>
- <p>Building with link time optimization requires cooperation from the
-system linker. LTO support on Linux systems requires that you use
-the <a href="http://sourceware.org/binutils">gold linker</a> which supports
-LTO via plugins. This is the same mechanism used by the
-<a href="http://gcc.gnu.org/wiki/LinkTimeOptimization">GCC LTO</a>
-project.</p>
- <p>The LLVM gold plugin implements the
-<a href="http://gcc.gnu.org/wiki/whopr/driver">gold plugin interface</a>
-on top of
-<a href="LinkTimeOptimization.html#lto">libLTO</a>.
-The same plugin can also be used by other tools such as <tt>ar</tt> and
-<tt>nm</tt>.
-</div>
-<!--=========================================================================-->
-<h2><a name="build">How to build it</a></h2>
-<!--=========================================================================-->
-<div>
- <p>You need to have gold with plugin support and build the LLVMgold
-plugin. Check whether you have gold running <tt>/usr/bin/ld -v</tt>. It will
-report &#8220;GNU gold&#8221; or else &#8220GNU ld&#8221; if not. If you have
-gold, check for plugin support by running <tt>/usr/bin/ld -plugin</tt>. If it
-complains &#8220missing argument&#8221 then you have plugin support. If not,
-such as an &#8220;unknown option&#8221; error then you will either need to
-build gold or install a version with plugin support.</p>
-<ul>
- <li>To build gold with plugin support:
- <pre class="doc_code">
-mkdir binutils
-cd binutils
-cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src login
-<em>{enter "anoncvs" as the password}</em>
-cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src co binutils
-mkdir build
-cd build
-../src/configure --enable-gold --enable-plugins
-make all-gold
-</pre>
- That should leave you with <tt>binutils/build/gold/ld-new</tt> which supports the <tt>-plugin</tt> option. It also built would have
-<tt>binutils/build/binutils/ar</tt> and <tt>nm-new</tt> which support plugins
-but don't have a visible -plugin option, instead relying on the gold plugin
-being present in <tt>../lib/bfd-plugins</tt> relative to where the binaries are
-placed.
- <li>Build the LLVMgold plugin: Configure LLVM with
- <tt>--with-binutils-include=/path/to/binutils/src/include</tt> and run
- <tt>make</tt>.
-</ul>
-</div>
-<!--=========================================================================-->
-<h2><a name="usage">Usage</a></h2>
-<!--=========================================================================-->
-<div>
-
- <p>The linker takes a <tt>-plugin</tt> option that points to the path of
- the plugin <tt>.so</tt> file. To find out what link command <tt>gcc</tt>
- would run in a given situation, run <tt>gcc -v <em>[...]</em></tt> and look
- for the line where it runs <tt>collect2</tt>. Replace that with
- <tt>ld-new -plugin /path/to/LLVMgold.so</tt> to test it out. Once you're
- ready to switch to using gold, backup your existing <tt>/usr/bin/ld</tt>
- then replace it with <tt>ld-new</tt>.</p>
-
- <p>You can produce bitcode files from <tt>clang</tt> using
- <tt>-emit-llvm</tt> or <tt>-flto</tt>, or the <tt>-O4</tt> flag which is
- synonymous with <tt>-O3 -flto</tt>.</p>
-
- <p>Any of these flags will also cause <tt>clang</tt> to look for the
- gold plugin in the <tt>lib</tt> directory under its prefix and pass the
- <tt>-plugin</tt> option to <tt>ld</tt>. It will not look for an alternate
- linker, which is why you need gold to be the installed system linker in
- your path.</p>
-
- <p>If you want <tt>ar</tt> and <tt>nm</tt> to work seamlessly as well, install
- <tt>LLVMgold.so</tt> to <tt>/usr/lib/bfd-plugins</tt>. If you built your
- own gold, be sure to install the <tt>ar</tt> and <tt>nm-new</tt> you built to
- <tt>/usr/bin</tt>.<p>
-
-<!-- ======================================================================= -->
-<h3>
- <a name="example1">Example of link time optimization</a>
-</h3>
-
-<div>
- <p>The following example shows a worked example of the gold plugin mixing
- LLVM bitcode and native code.
-<pre class="doc_code">
---- a.c ---
-#include &lt;stdio.h&gt;
-
-extern void foo1(void);
-extern void foo4(void);
-
-void foo2(void) {
- printf("Foo2\n");
-}
-
-void foo3(void) {
- foo4();
-}
-
-int main(void) {
- foo1();
-}
-
---- b.c ---
-#include &lt;stdio.h&gt;
-
-extern void foo2(void);
-
-void foo1(void) {
- foo2();
-}
-
-void foo4(void) {
- printf("Foo4");
-}
-
---- command lines ---
-$ clang -flto a.c -c -o a.o # &lt;-- a.o is LLVM bitcode file
-$ ar q a.a a.o # &lt;-- a.a is an archive with LLVM bitcode
-$ clang b.c -c -o b.o # &lt;-- b.o is native object file
-$ clang -flto a.a b.o -o main # &lt;-- link with LLVMgold plugin
-</pre>
-
- <p>Gold informs the plugin that foo3 is never referenced outside the IR,
- leading LLVM to delete that function. However, unlike in the
- <a href="LinkTimeOptimization.html#example1">libLTO
- example</a> gold does not currently eliminate foo4.</p>
-</div>
-
-</div>
-
-<!--=========================================================================-->
-<h2>
- <a name="lto_autotools">
- Quickstart for using LTO with autotooled projects
- </a>
-</h2>
-<!--=========================================================================-->
-<div>
- <p>Once your system <tt>ld</tt>, <tt>ar</tt>, and <tt>nm</tt> all support LLVM
- bitcode, everything is in place for an easy to use LTO build of autotooled
- projects:</p>
-
- <ul>
- <li>Follow the instructions <a href="#build">on how to build LLVMgold.so</a>.</li>
- <li>Install the newly built binutils to <tt>$PREFIX</tt></li>
- <li>Copy <tt>Release/lib/LLVMgold.so</tt> to
- <tt>$PREFIX/lib/bfd-plugins/</tt></li>
- <li>Set environment variables (<tt>$PREFIX</tt> is where you installed clang and
- binutils):
-<pre class="doc_code">
-export CC="$PREFIX/bin/clang -flto"
-export CXX="$PREFIX/bin/clang++ -flto"
-export AR="$PREFIX/bin/ar"
-export NM="$PREFIX/bin/nm"
-export RANLIB=/bin/true #ranlib is not needed, and doesn't support .bc files in .a
-export CFLAGS="-O4"
-</pre>
- </li>
- <li>Or you can just set your path:
-<pre class="doc_code">
-export PATH="$PREFIX/bin:$PATH"
-export CC="clang -flto"
-export CXX="clang++ -flto"
-export RANLIB=/bin/true
-export CFLAGS="-O4"
-</pre></li>
- <li>Configure &amp; build the project as usual:
-<pre class="doc_code">
-% ./configure &amp;&amp; make &amp;&amp; make check
-</pre></li>
- </ul>
-
- <p>The environment variable settings may work for non-autotooled projects
- too, but you may need to set the <tt>LD</tt> environment variable as
- well.</p>
-</div>
-
-<!--=========================================================================-->
-<h2><a name="licensing">Licensing</a></h2>
-<!--=========================================================================-->
-<div>
- <p>Gold is licensed under the GPLv3. LLVMgold uses the interface file
-<tt>plugin-api.h</tt> from gold which means that the resulting LLVMgold.so
-binary is also GPLv3. This can still be used to link non-GPLv3 programs just
-as much as gold could without the plugin.</p>
-</div>
-
-<!-- *********************************************************************** -->
-<hr>
-<address>
- <a href="http://jigsaw.w3.org/css-validator/check/referer"><img
- src="http://jigsaw.w3.org/css-validator/images/vcss-blue" alt="Valid CSS"></a>
- <a href="http://validator.w3.org/check/referer"><img
- src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
- <a href="mailto:nicholas@metrix.on.ca">Nick Lewycky</a><br>
- <a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2010-04-16 23:58:21 -0800 (Fri, 16 Apr 2010) $
-</address>
-</body>
-</html>
diff --git a/docs/GoldPlugin.rst b/docs/GoldPlugin.rst
new file mode 100644
index 0000000000..300aea9f9a
--- /dev/null
+++ b/docs/GoldPlugin.rst
@@ -0,0 +1,186 @@
+.. _gold-plugin:
+
+====================
+The LLVM gold plugin
+====================
+
+.. sectionauthor:: Nick Lewycky
+
+Introduction
+============
+
+Building with link time optimization requires cooperation from
+the system linker. LTO support on Linux systems requires that you use the
+`gold linker`_ which supports LTO via plugins. This is the same mechanism
+used by the `GCC LTO`_ project.
+
+The LLVM gold plugin implements the gold plugin interface on top of
+:ref:`libLTO`. The same plugin can also be used by other tools such as
+``ar`` and ``nm``.
+
+.. _`gold linker`: http://sourceware.org/binutils
+.. _`GCC LTO`: http://gcc.gnu.org/wiki/LinkTimeOptimization
+.. _`gold plugin interface`: http://gcc.gnu.org/wiki/whopr/driver
+
+.. _lto-how-to-build:
+
+How to build it
+===============
+
+You need to have gold with plugin support and build the LLVMgold plugin.
+Check whether you have gold running ``/usr/bin/ld -v``. It will report "GNU
+gold" or else "GNU ld" if not. If you have gold, check for plugin support
+by running ``/usr/bin/ld -plugin``. If it complains "missing argument" then
+you have plugin support. If not, such as an "unknown option" error then you
+will either need to build gold or install a version with plugin support.
+
+* To build gold with plugin support:
+
+ .. code-block:: bash
+
+ $ mkdir binutils
+ $ cd binutils
+ $ cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src login
+ {enter "anoncvs" as the password}
+ $ cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src co binutils
+ $ mkdir build
+ $ cd build
+ $ ../src/configure --enable-gold --enable-plugins
+ $ make all-gold
+
+ That should leave you with ``binutils/build/gold/ld-new`` which supports
+ the ``-plugin`` option. It also built would have
+ ``binutils/build/binutils/ar`` and ``nm-new`` which support plugins but
+ don't have a visible -plugin option, instead relying on the gold plugin
+ being present in ``../lib/bfd-plugins`` relative to where the binaries
+ are placed.
+
+* Build the LLVMgold plugin: Configure LLVM with
+ ``--with-binutils-include=/path/to/binutils/src/include`` and run
+ ``make``.
+
+Usage
+=====
+
+The linker takes a ``-plugin`` option that points to the path of
+the plugin ``.so`` file. To find out what link command ``gcc``
+would run in a given situation, run ``gcc -v [...]`` and
+look for the line where it runs ``collect2``. Replace that with
+``ld-new -plugin /path/to/LLVMgold.so`` to test it out. Once you're
+ready to switch to using gold, backup your existing ``/usr/bin/ld``
+then replace it with ``ld-new``.
+
+You can produce bitcode files from ``clang`` using ``-emit-llvm`` or
+``-flto``, or the ``-O4`` flag which is synonymous with ``-O3 -flto``.
+
+Any of these flags will also cause ``clang`` to look for the gold plugin in
+the ``lib`` directory under its prefix and pass the ``-plugin`` option to
+``ld``. It will not look for an alternate linker, which is why you need
+gold to be the installed system linker in your path.
+
+If you want ``ar`` and ``nm`` to work seamlessly as well, install
+``LLVMgold.so`` to ``/usr/lib/bfd-plugins``. If you built your own gold, be
+sure to install the ``ar`` and ``nm-new`` you built to ``/usr/bin``.
+
+
+Example of link time optimization
+---------------------------------
+
+The following example shows a worked example of the gold plugin mixing LLVM
+bitcode and native code.
+
+.. code-block:: c
+
+ --- a.c ---
+ #include <stdio.h>
+
+ extern void foo1(void);
+ extern void foo4(void);
+
+ void foo2(void) {
+ printf("Foo2\n");
+ }
+
+ void foo3(void) {
+ foo4();
+ }
+
+ int main(void) {
+ foo1();
+ }
+
+ --- b.c ---
+ #include <stdio.h>
+
+ extern void foo2(void);
+
+ void foo1(void) {
+ foo2();
+ }
+
+ void foo4(void) {
+ printf("Foo4");
+ }
+
+.. code-block:: bash
+
+ --- command lines ---
+ $ clang -flto a.c -c -o a.o # <-- a.o is LLVM bitcode file
+ $ ar q a.a a.o # <-- a.a is an archive with LLVM bitcode
+ $ clang b.c -c -o b.o # <-- b.o is native object file
+ $ clang -flto a.a b.o -o main # <-- link with LLVMgold plugin
+
+Gold informs the plugin that foo3 is never referenced outside the IR,
+leading LLVM to delete that function. However, unlike in the :ref:`libLTO
+example <libLTO-example>` gold does not currently eliminate foo4.
+
+Quickstart for using LTO with autotooled projects
+=================================================
+
+Once your system ``ld``, ``ar``, and ``nm`` all support LLVM bitcode,
+everything is in place for an easy to use LTO build of autotooled projects:
+
+* Follow the instructions :ref:`on how to build LLVMgold.so
+ <lto-how-to-build>`.
+
+* Install the newly built binutils to ``$PREFIX``
+
+* Copy ``Release/lib/LLVMgold.so`` to ``$PREFIX/lib/bfd-plugins/``
+
+* Set environment variables (``$PREFIX`` is where you installed clang and
+ binutils):
+
+ .. code-block:: bash
+
+ export CC="$PREFIX/bin/clang -flto"
+ export CXX="$PREFIX/bin/clang++ -flto"
+ export AR="$PREFIX/bin/ar"
+ export NM="$PREFIX/bin/nm"
+ export RANLIB=/bin/true #ranlib is not needed, and doesn't support .bc files in .a
+ export CFLAGS="-O4"
+
+* Or you can just set your path:
+
+ .. code-block:: bash
+
+ export PATH="$PREFIX/bin:$PATH"
+ export CC="clang -flto"
+ export CXX="clang++ -flto"
+ export RANLIB=/bin/true
+ export CFLAGS="-O4"
+* Configure and build the project as usual:
+
+ .. code-block:: bash
+
+ % ./configure && make && make check
+
+The environment variable settings may work for non-autotooled projects too,
+but you may need to set the ``LD`` environment variable as well.
+
+Licensing
+=========
+
+Gold is licensed under the GPLv3. LLVMgold uses the interface file
+``plugin-api.h`` from gold which means that the resulting ``LLVMgold.so``
+binary is also GPLv3. This can still be used to link non-GPLv3 programs
+just as much as gold could without the plugin.
diff --git a/docs/HowToSetUpLLVMStyleRTTI.rst b/docs/HowToSetUpLLVMStyleRTTI.rst
new file mode 100644
index 0000000000..b5c1b78afe
--- /dev/null
+++ b/docs/HowToSetUpLLVMStyleRTTI.rst
@@ -0,0 +1,281 @@
+.. _how-to-set-up-llvm-style-rtti:
+
+======================================================
+How to set up LLVM-style RTTI for your class hierarchy
+======================================================
+
+.. sectionauthor:: Sean Silva <silvas@purdue.edu>
+
+.. contents::
+
+Background
+==========
+
+LLVM avoids using C++'s built in RTTI. Instead, it pervasively uses its
+own hand-rolled form of RTTI which is much more efficient and flexible,
+although it requires a bit more work from you as a class author.
+
+A description of how to use LLVM-style RTTI from a client's perspective is
+given in the `Programmer's Manual <ProgrammersManual.html#isa>`_. This
+document, in contrast, discusses the steps you need to take as a class
+hierarchy author to make LLVM-style RTTI available to your clients.
+
+Before diving in, make sure that you are familiar with the Object Oriented
+Programming concept of "`is-a`_".
+
+.. _is-a: http://en.wikipedia.org/wiki/Is-a
+
+Basic Setup
+===========
+
+This section describes how to set up the most basic form of LLVM-style RTTI
+(which is sufficient for 99.9% of the cases). We will set up LLVM-style
+RTTI for this class hierarchy:
+
+.. code-block:: c++
+
+ class Shape {
+ public:
+ Shape() {}
+ virtual double computeArea() = 0;
+ };
+
+ class Square : public Shape {
+ double SideLength;
+ public:
+ Square(double S) : SideLength(S) {}
+ double computeArea() /* override */;
+ };
+
+ class Circle : public Shape {
+ double Radius;
+ public:
+ Circle(double R) : Radius(R) {}
+ double computeArea() /* override */;
+ };
+
+The most basic working setup for LLVM-style RTTI requires the following
+steps:
+
+#. In the header where you declare ``Shape``, you will want to ``#include
+ "llvm/Support/Casting.h"``, which declares LLVM's RTTI templates. That
+ way your clients don't even have to think about it.
+
+ .. code-block:: c++
+
+ #include "llvm/Support/Casting.h"
+
+
+#. In the base class, introduce an enum which discriminates all of the
+ different classes in the hierarchy, and stash the enum value somewhere in
+ the base class.
+
+ Here is the code after introducing this change:
+
+ .. code-block:: c++
+
+ class Shape {
+ public:
+ + /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
+ + enum ShapeKind {
+ + SquareKind,
+ + CircleKind
+ + };
+ +private:
+ + const ShapeKind Kind;
+ +public:
+ + ShapeKind getKind() const { return Kind; }
+ +
+ Shape() {}
+ virtual double computeArea() = 0;
+ };
+
+ You will usually want to keep the ``Kind`` member encapsulated and
+ private, but let the enum ``ShapeKind`` be public along with providing a
+ ``getKind()`` method. This is convenient for clients so that they can do
+ a ``switch`` over the enum.
+
+ A common naming convention is that these enums are "kind"s, to avoid
+ ambiguity with the words "type" or "class" which have overloaded meanings
+ in many contexts within LLVM. Sometimes there will be a natural name for
+ it, like "opcode". Don't bikeshed over this; when in doubt use ``Kind``.
+
+ You might wonder why the ``Kind`` enum doesn't have an entry for
+ ``Shape``. The reason for this is that since ``Shape`` is abstract
+ (``computeArea() = 0;``), you will never actually have non-derived
+ instances of exactly that class (only subclasses). See `Concrete Bases
+ and Deeper Hierarchies`_ for information on how to deal with
+ non-abstract bases. It's worth mentioning here that unlike
+ ``dynamic_cast<>``, LLVM-style RTTI can be used (and is often used) for
+ classes that don't have v-tables.
+
+#. Next, you need to make sure that the ``Kind`` gets initialized to the
+ value corresponding to the dynamic type of the class. Typically, you will
+ want to have it be an argument to the constructor of the base class, and
+ then pass in the respective ``XXXKind`` from subclass constructors.
+
+ Here is the code after that change:
+
+ .. code-block:: c++
+
+ class Shape {
+ public:
+ /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
+ enum ShapeKind {
+ SquareKind,
+ CircleKind
+ };
+ private:
+ const ShapeKind Kind;
+ public:
+ ShapeKind getKind() const { return Kind; }
+
+ - Shape() {}
+ + Shape(ShapeKind K) : Kind(K) {}
+ virtual double computeArea() = 0;
+ };
+
+ class Square : public Shape {
+ double SideLength;
+ public:
+ - Square(double S) : SideLength(S) {}
+ + Square(double S) : Shape(SquareKind), SideLength(S) {}
+ double computeArea() /* override */;
+ };
+
+ class Circle : public Shape {
+ double Radius;
+ public:
+ - Circle(double R) : Radius(R) {}
+ + Circle(double R) : Shape(CircleKind), Radius(R) {}
+ double computeArea() /* override */;
+ };
+
+#. Finally, you need to inform LLVM's RTTI templates how to dynamically
+ determine the type of a class (i.e. whether the ``isa<>``/``dyn_cast<>``
+ should succeed). The default "99.9% of use cases" way to accomplish this
+ is through a small static member function ``classof``. In order to have
+ proper context for an explanation, we will display this code first, and
+ then below describe each part:
+
+ .. code-block:: c++
+
+ class Shape {
+ public:
+ /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
+ enum ShapeKind {
+ SquareKind,
+ CircleKind
+ };
+ private:
+ const ShapeKind Kind;
+ public:
+ ShapeKind getKind() const { return Kind; }
+
+ Shape(ShapeKind K) : Kind(K) {}
+ virtual double computeArea() = 0;
+ +
+ + static bool classof(const Shape *) { return true; }
+ };
+
+ class Square : public Shape {
+ double SideLength;
+ public:
+ Square(double S) : Shape(SquareKind), SideLength(S) {}
+ double computeArea() /* override */;
+ +
+ + static bool classof(const Square *) { return true; }
+ + static bool classof(const Shape *S) {
+ + return S->getKind() == SquareKind;
+ + }
+ };
+
+ class Circle : public Shape {
+ double Radius;
+ public:
+ Circle(double R) : Shape(CircleKind), Radius(R) {}
+ double computeArea() /* override */;
+ +
+ + static bool classof(const Circle *) { return true; }
+ + static bool classof(const Shape *S) {
+ + return S->getKind() == CircleKind;
+ + }
+ };
+
+ Basically, the job of ``classof`` is to return ``true`` if its argument
+ is of the enclosing class's type. As you can see, there are two general
+ overloads of ``classof`` in use here.
+
+ #. The first, which just returns ``true``, means that if we know that the
+ argument of the cast is of the enclosing type *at compile time*, then
+ we don't need to bother to check anything since we already know that
+ the type is convertible. This is an optimization for the case that we
+ statically know the conversion is OK.
+
+ #. The other overload takes a pointer to an object of the base of the
+ class hierarchy: this is the "general case" of the cast. We need to
+ check the ``Kind`` to dynamically decide if the argument is of (or
+ derived from) the enclosing type.
+
+ To be more precise, let ``classof`` be inside a class ``C``. Then the
+ contract for ``classof`` is "return ``true`` if the argument is-a
+ ``C``". As long as your implementation fulfills this contract, you can
+ tweak and optimize it as much as you want.
+
+Although for this small example setting up LLVM-style RTTI seems like a lot
+of "boilerplate", if your classes are doing anything interesting then this
+will end up being a tiny fraction of the code.
+
+Concrete Bases and Deeper Hierarchies
+=====================================
+
+For concrete bases (i.e. non-abstract interior nodes of the inheritance
+tree), the ``Kind`` check inside ``classof`` needs to be a bit more
+complicated. Say that ``SpecialSquare`` and ``OtherSpecialSquare`` derive
+from ``Square``, and so ``ShapeKind`` becomes:
+
+.. code-block:: c++
+
+ enum ShapeKind {
+ SquareKind,
+ + SpecialSquareKind,
+ + OtherSpecialSquareKind,
+ CircleKind
+ }
+
+Then in ``Square``, we would need to modify the ``classof`` like so:
+
+.. code-block:: c++
+
+ static bool classof(const Square *) { return true; }
+ - static bool classof(const Shape *S) {
+ - return S->getKind() == SquareKind;
+ - }
+ + static bool classof(const Shape *S) {
+ + return S->getKind() >= SquareKind &&
+ + S->getKind() <= OtherSpecialSquareKind;
+ + }
+
+The reason that we need to test a range like this instead of just equality
+is that both ``SpecialSquare`` and ``OtherSpecialSquare`` "is-a"
+``Square``, and so ``classof`` needs to return ``true`` for them.
+
+This approach can be made to scale to arbitrarily deep hierarchies. The
+trick is that you arrange the enum values so that they correspond to a
+preorder traversal of the class hierarchy tree. With that arrangement, all
+subclass tests can be done with two comparisons as shown above. If you just
+list the class hierarchy like a list of bullet points, you'll get the
+ordering right::
+
+ | Shape
+ | Square
+ | SpecialSquare
+ | OtherSpecialSquare
+ | Circle
+
+.. TODO::
+
+ Touch on some of the more advanced features, like ``isa_impl`` and
+ ``simplify_type``. However, those two need reference documentation in
+ the form of doxygen comments as well. We need the doxygen so that we can
+ say "for full details, see http://llvm.org/doxygen/..."
diff --git a/docs/LangRef.html b/docs/LangRef.html
index 89b9227b72..167397ff53 100644
--- a/docs/LangRef.html
+++ b/docs/LangRef.html
@@ -1107,9 +1107,9 @@ declare signext i8 @returns_signed_char()
<dd>This indicates that the pointer parameter specifies the address of a
structure that is the return value of the function in the source program.
This pointer must be guaranteed by the caller to be valid: loads and
- stores to the structure may be assumed by the callee to not to trap. This
- may only be applied to the first parameter. This is not a valid attribute
- for return values. </dd>
+ stores to the structure may be assumed by the callee to not to trap and
+ to be properly aligned. This may only be applied to the first parameter.
+ This is not a valid attribute for return values. </dd>
<dt><tt><b><a name="noalias">noalias</a></b></tt></dt>
<dd>This indicates that pointer values
@@ -2104,7 +2104,7 @@ in signal handlers).</p>
<p>Structures may optionally be "packed" structures, which indicate that the
alignment of the struct is one byte, and that there is no padding between
the elements. In non-packed structs, padding between field types is inserted
- as defined by the TargetData string in the module, which is required to match
+ as defined by the DataLayout string in the module, which is required to match
what the underlying code generator expects.</p>
<p>Structures can either be "literal" or "identified". A literal structure is
diff --git a/docs/LinkTimeOptimization.rst b/docs/LinkTimeOptimization.rst
index 53d673e406..7eacf0bd0d 100644
--- a/docs/LinkTimeOptimization.rst
+++ b/docs/LinkTimeOptimization.rst
@@ -29,6 +29,8 @@ bitcode files. This tight integration between the linker and LLVM optimizer
helps to do optimizations that are not possible in other models. The linker
input allows the optimizer to avoid relying on conservative escape analysis.
+.. _libLTO-example:
+
Example of link time optimization
---------------------------------
diff --git a/docs/ProgrammersManual.html b/docs/ProgrammersManual.html
index 036c387d7a..64ddb9d105 100644
--- a/docs/ProgrammersManual.html
+++ b/docs/ProgrammersManual.html
@@ -98,6 +98,7 @@ option</a></li>
<li><a href="#dss_valuemap">"llvm/ADT/ValueMap.h"</a></li>
<li><a href="#dss_intervalmap">"llvm/ADT/IntervalMap.h"</a></li>
<li><a href="#dss_map">&lt;map&gt;</a></li>
+ <li><a href="#dss_mapvector">"llvm/ADT/MapVector.h"</a></li>
<li><a href="#dss_inteqclasses">"llvm/ADT/IntEqClasses.h"</a></li>
<li><a href="#dss_immutablemap">"llvm/ADT/ImmutableMap.h"</a></li>
<li><a href="#dss_othermap">Other Map-Like Container Options</a></li>
@@ -432,10 +433,10 @@ if (<a href="#AllocationInst">AllocationInst</a> *AI = dyn_cast&lt;<a href="#All
</dl>
<p>These five templates can be used with any classes, whether they have a
-v-table or not. To add support for these templates, you simply need to add
-<tt>classof</tt> static methods to the class you are interested casting
-to. Describing this is currently outside the scope of this document, but there
-are lots of examples in the LLVM source base.</p>
+v-table or not. If you want to add support for these templates, see the
+document <a href="HowToSetUpLLVMStyleRTTI.html">How to set up LLVM-style
+RTTI for your class hierarchy </a>.
+</p>
</div>
@@ -1848,6 +1849,24 @@ another element takes place).</p>
</div>
+
+<!-- _______________________________________________________________________ -->
+<h4>
+ <a name="dss_mapvector">"llvm/ADT/MapVector.h"</a>
+</h4>
+<div>
+
+<p> MapVector&lt;KeyT,ValueT&gt provides a subset of the DenseMap interface.
+ The main difference is that the iteration order is guaranteed to be
+ the insertion order, making it an easy (but somewhat expensive) solution
+ for non-deterministic iteration over maps of pointers. </p>
+
+<p> It is implemented by mapping from key to an index in a vector of key,value
+ pairs. This provides fast lookup and iteration, but has two main drawbacks:
+ The key is stored twice and it doesn't support removing elements. </p>
+
+</div>
+
<!-- _______________________________________________________________________ -->
<h4>
<a name="dss_inteqclasses">"llvm/ADT/IntEqClasses.h"</a>
diff --git a/docs/SourceLevelDebugging.html b/docs/SourceLevelDebugging.html
index 918383bc21..546aab9d1a 100644
--- a/docs/SourceLevelDebugging.html
+++ b/docs/SourceLevelDebugging.html
@@ -2367,11 +2367,11 @@ bucket contents:
| HEADER.header_data_len | uint32_t
| HEADER_DATA | HeaderData
|-------------------------|
-| BUCKETS | uint32_t[n_buckets] // 32 bit hash indexes
+| BUCKETS | uint32_t[bucket_count] // 32 bit hash indexes
|-------------------------|
-| HASHES | uint32_t[n_buckets] // 32 bit hash values
+| HASHES | uint32_t[hashes_count] // 32 bit hash values
|-------------------------|
-| OFFSETS | uint32_t[n_buckets] // 32 bit offsets to hash value data
+| OFFSETS | uint32_t[hashes_count] // 32 bit offsets to hash value data
|-------------------------|
| ALL HASH DATA |
`-------------------------'
diff --git a/docs/WritingAnLLVMBackend.html b/docs/WritingAnLLVMBackend.html
index 441d122f53..7576d490d7 100644
--- a/docs/WritingAnLLVMBackend.html
+++ b/docs/WritingAnLLVMBackend.html
@@ -314,14 +314,14 @@ represent target components. These methods are named <tt>get*Info</tt>, and are
intended to obtain the instruction set (<tt>getInstrInfo</tt>), register set
(<tt>getRegisterInfo</tt>), stack frame layout (<tt>getFrameInfo</tt>), and
similar information. <tt>XXXTargetMachine</tt> must also implement the
-<tt>getTargetData</tt> method to access an object with target-specific data
+<tt>getDataLayout</tt> method to access an object with target-specific data
characteristics, such as data type size and alignment requirements.
</p>
<p>
For instance, for the SPARC target, the header file
<tt>SparcTargetMachine.h</tt> declares prototypes for several <tt>get*Info</tt>
-and <tt>getTargetData</tt> methods that simply return a class member.
+and <tt>getDataLayout</tt> methods that simply return a class member.
</p>
<div class="doc_code">
@@ -331,7 +331,7 @@ namespace llvm {
class Module;
class SparcTargetMachine : public LLVMTargetMachine {
- const TargetData DataLayout; // Calculates type size &amp; alignment
+ const DataLayout DataLayout; // Calculates type size &amp; alignment
SparcSubtarget Subtarget;
SparcInstrInfo InstrInfo;
TargetFrameInfo FrameInfo;
@@ -348,7 +348,7 @@ public:
virtual const TargetRegisterInfo *getRegisterInfo() const {
return &amp;InstrInfo.getRegisterInfo();
}
- virtual const TargetData *getTargetData() const { return &amp;DataLayout; }
+ virtual const DataLayout *getDataLayout() const { return &amp;DataLayout; }
static unsigned getModuleMatchQuality(const Module &amp;M);
// Pass Pipeline Configuration
@@ -364,7 +364,7 @@ public:
<li><tt>getInstrInfo()</tt></li>
<li><tt>getRegisterInfo()</tt></li>
<li><tt>getFrameInfo()</tt></li>
-<li><tt>getTargetData()</tt></li>
+<li><tt>getDataLayout()</tt></li>
<li><tt>getSubtargetImpl()</tt></li>
</ul>
diff --git a/docs/_themes/llvm-theme/static/llvm-theme.css b/docs/_themes/llvm-theme/static/llvm-theme.css
index f684d00ce4..beab2ca251 100644
--- a/docs/_themes/llvm-theme/static/llvm-theme.css
+++ b/docs/_themes/llvm-theme/static/llvm-theme.css
@@ -18,7 +18,6 @@ body {
font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva',
'Verdana', sans-serif;
font-size: 14px;
- letter-spacing: -0.01em;
line-height: 150%;
text-align: center;
background-color: #BFD1D4;
@@ -239,7 +238,6 @@ cite, code, tt {
font-family: 'Consolas', 'Deja Vu Sans Mono',
'Bitstream Vera Sans Mono', monospace;
font-size: 0.95em;
- letter-spacing: 0.01em;
}
:not(a.reference) > tt {
@@ -274,7 +272,6 @@ pre {
font-family: 'Consolas', 'Deja Vu Sans Mono',
'Bitstream Vera Sans Mono', monospace;
font-size: 0.95em;
- letter-spacing: 0.015em;
line-height: 120%;
padding: 0.5em;
border: 1px solid #ccc;
diff --git a/docs/index.rst b/docs/index.rst
index 50f76a3e3f..d406b52574 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -26,7 +26,7 @@ targeted at different audiences:
* **User Guides**
- Those new to the LLVM system should first vist the :ref:`userguides`.
+ Those new to the LLVM system should first visit the :ref:`userguides`.
NOTE: If you are a user who is only interested in using LLVM-based
compilers, you should look into `Clang <http://clang.llvm.org>`_ or
diff --git a/docs/programming.rst b/docs/programming.rst
index 5d000cb3c2..c4eec59417 100644
--- a/docs/programming.rst
+++ b/docs/programming.rst
@@ -6,9 +6,12 @@ Programming Documentation
.. toctree::
:hidden:
+ Atomics
CodingStandards
CommandLine
- Atomics
+ CompilerWriterInfo
+ ExtendingLLVM
+ HowToSetUpLLVMStyleRTTI
* `LLVM Language Reference Manual <LangRef.html>`_
@@ -33,7 +36,12 @@ Programming Documentation
Details the LLVM coding standards and provides useful information on writing
efficient C++ code.
-* `Extending LLVM <ExtendingLLVM.html>`_
+* :doc:`HowToSetUpLLVMStyleRTTI`
+
+ How to make ``isa<>``, ``dyn_cast<>``, etc. available for clients of your
+ class hierarchy.
+
+* :ref:`extending_llvm`
Look here to see how to add instructions and intrinsics to LLVM.
@@ -43,3 +51,7 @@ Programming Documentation
(`tarball <http://llvm.org/doxygen/doxygen.tar.gz>`_)
* `ViewVC Repository Browser <http://llvm.org/viewvc/>`_
+
+* :ref:`compiler_writer_info`
+
+ A list of helpful links for compiler writers.
diff --git a/docs/subsystems.rst b/docs/subsystems.rst
index 6c20a61c60..8c3cdf2417 100644
--- a/docs/subsystems.rst
+++ b/docs/subsystems.rst
@@ -16,6 +16,7 @@ Subsystem Documentation
SegmentedStacks
TableGenFundamentals
DebuggingJITedCode
+ GoldPlugin
* `Writing an LLVM Pass <WritingAnLLVMPass.html>`_
@@ -75,7 +76,7 @@ Subsystem Documentation
This document describes the interface between LLVM intermodular optimizer
and the linker and its design
-* `The LLVM gold plugin <GoldPlugin.html>`_
+* :ref:`gold-plugin`
How to build your programs with link-time optimization on Linux.
diff --git a/docs/tutorial/LangImpl4.html b/docs/tutorial/LangImpl4.html
index 453e43a02e..53695924b2 100644
--- a/docs/tutorial/LangImpl4.html
+++ b/docs/tutorial/LangImpl4.html
@@ -173,7 +173,7 @@ add a set of optimizations to run. The code looks like this:</p>
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
- OurFPM.add(new TargetData(*TheExecutionEngine->getTargetData()));
+ OurFPM.add(new DataLayout(*TheExecutionEngine->getDataLayout()));
// Provide basic AliasAnalysis support for GVN.
OurFPM.add(createBasicAliasAnalysisPass());
// Do simple "peephole" optimizations and bit-twiddling optzns.
@@ -523,7 +523,7 @@ at runtime.</p>
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/TargetSelect.h"
#include &lt;cstdio&gt;
@@ -1103,7 +1103,7 @@ int main() {
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
- OurFPM.add(new TargetData(*TheExecutionEngine-&gt;getTargetData()));
+ OurFPM.add(new DataLayout(*TheExecutionEngine-&gt;getDataLayout()));
// Provide basic AliasAnalysis support for GVN.
OurFPM.add(createBasicAliasAnalysisPass());
// Do simple "peephole" optimizations and bit-twiddling optzns.
diff --git a/docs/tutorial/LangImpl5.html b/docs/tutorial/LangImpl5.html
index 2d406df3aa..768d9a0e11 100644
--- a/docs/tutorial/LangImpl5.html
+++ b/docs/tutorial/LangImpl5.html
@@ -901,7 +901,7 @@ clang++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/TargetSelect.h"
#include &lt;cstdio&gt;
@@ -1723,7 +1723,7 @@ int main() {
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
- OurFPM.add(new TargetData(*TheExecutionEngine-&gt;getTargetData()));
+ OurFPM.add(new DataLayout(*TheExecutionEngine-&gt;getDataLayout()));
// Provide basic AliasAnalysis support for GVN.
OurFPM.add(createBasicAliasAnalysisPass());
// Do simple "peephole" optimizations and bit-twiddling optzns.
diff --git a/docs/tutorial/LangImpl6.html b/docs/tutorial/LangImpl6.html
index a76298012f..bf502e7da9 100644
--- a/docs/tutorial/LangImpl6.html
+++ b/docs/tutorial/LangImpl6.html
@@ -840,7 +840,7 @@ library, although doing that will cause problems on Windows.</p>
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/TargetSelect.h"
#include &lt;cstdio&gt;
@@ -1780,7 +1780,7 @@ int main() {
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
- OurFPM.add(new TargetData(*TheExecutionEngine-&gt;getTargetData()));
+ OurFPM.add(new DataLayout(*TheExecutionEngine-&gt;getDataLayout()));
// Provide basic AliasAnalysis support for GVN.
OurFPM.add(createBasicAliasAnalysisPass());
// Do simple "peephole" optimizations and bit-twiddling optzns.
diff --git a/docs/tutorial/LangImpl7.html b/docs/tutorial/LangImpl7.html
index 08c0c716b6..8fa99b1903 100644
--- a/docs/tutorial/LangImpl7.html
+++ b/docs/tutorial/LangImpl7.html
@@ -524,7 +524,7 @@ good codegen once again:</p>
<pre>
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
- OurFPM.add(new TargetData(*TheExecutionEngine-&gt;getTargetData()));
+ OurFPM.add(new DataLayout(*TheExecutionEngine-&gt;getDataLayout()));
<b>// Promote allocas to registers.
OurFPM.add(createPromoteMemoryToRegisterPass());</b>
// Do simple "peephole" optimizations and bit-twiddling optzns.
@@ -1008,7 +1008,7 @@ clang++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/TargetSelect.h"
#include &lt;cstdio&gt;
@@ -2113,7 +2113,7 @@ int main() {
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
- OurFPM.add(new TargetData(*TheExecutionEngine-&gt;getTargetData()));
+ OurFPM.add(new DataLayout(*TheExecutionEngine-&gt;getDataLayout()));
// Provide basic AliasAnalysis support for GVN.
OurFPM.add(createBasicAliasAnalysisPass());
// Promote allocas to registers.
diff --git a/docs/tutorial/OCamlLangImpl4.html b/docs/tutorial/OCamlLangImpl4.html
index ca427eb0e0..eb97d986c2 100644
--- a/docs/tutorial/OCamlLangImpl4.html
+++ b/docs/tutorial/OCamlLangImpl4.html
@@ -189,7 +189,7 @@ add a set of optimizations to run. The code looks like this:</p>
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
- TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
+ DataLayout.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
(* Do simple "peephole" optimizations and bit-twiddling optzn. *)
add_instruction_combining the_fpm;
@@ -965,7 +965,7 @@ let main () =
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
- TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
+ DataLayout.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
(* Do simple "peephole" optimizations and bit-twiddling optzn. *)
add_instruction_combination the_fpm;
diff --git a/docs/tutorial/OCamlLangImpl5.html b/docs/tutorial/OCamlLangImpl5.html
index feeed6a533..d25f1dc9bb 100644
--- a/docs/tutorial/OCamlLangImpl5.html
+++ b/docs/tutorial/OCamlLangImpl5.html
@@ -1498,7 +1498,7 @@ let main () =
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
- TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
+ DataLayout.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
(* Do simple "peephole" optimizations and bit-twiddling optzn. *)
add_instruction_combination the_fpm;
diff --git a/docs/tutorial/OCamlLangImpl6.html b/docs/tutorial/OCamlLangImpl6.html
index 2ee5089721..56883d539b 100644
--- a/docs/tutorial/OCamlLangImpl6.html
+++ b/docs/tutorial/OCamlLangImpl6.html
@@ -1506,7 +1506,7 @@ let main () =
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
- TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
+ DataLayout.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
(* Do simple "peephole" optimizations and bit-twiddling optzn. *)
add_instruction_combination the_fpm;
diff --git a/docs/tutorial/OCamlLangImpl7.html b/docs/tutorial/OCamlLangImpl7.html
index d106ad0701..fd66b10c1a 100644
--- a/docs/tutorial/OCamlLangImpl7.html
+++ b/docs/tutorial/OCamlLangImpl7.html
@@ -545,7 +545,7 @@ let main () =
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
- TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
+ DataLayout.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
<b>(* Promote allocas to registers. *)
add_memory_to_register_promotion the_fpm;</b>
@@ -1834,7 +1834,7 @@ let main () =
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
- TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
+ DataLayout.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
(* Promote allocas to registers. *)
add_memory_to_register_promotion the_fpm;
diff --git a/docs/userguides.rst b/docs/userguides.rst
index c5dd979224..6ff46ade48 100644
--- a/docs/userguides.rst
+++ b/docs/userguides.rst
@@ -10,6 +10,7 @@ User Guides
HowToBuildOnARM
CommandGuide/index
DeveloperPolicy
+ GettingStarted
GettingStartedVS
FAQ
Lexicon
@@ -18,7 +19,7 @@ User Guides
yaml2obj
HowToSubmitABug
-* `The LLVM Getting Started Guide <GettingStarted.html>`_
+* :ref:`getting_started`
Discusses how to get up and running quickly with the LLVM infrastructure.
Everything from unpacking and compilation of the distribution to execution
diff --git a/examples/ExceptionDemo/ExceptionDemo.cpp b/examples/ExceptionDemo/ExceptionDemo.cpp
index 6dbd6626de..56d4d81b5c 100644
--- a/examples/ExceptionDemo/ExceptionDemo.cpp
+++ b/examples/ExceptionDemo/ExceptionDemo.cpp
@@ -57,7 +57,7 @@
#include "llvm/PassManager.h"
#include "llvm/Intrinsics.h"
#include "llvm/Analysis/Verifier.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/Dwarf.h"
@@ -1945,7 +1945,7 @@ int main(int argc, char *argv[]) {
// Set up the optimizer pipeline.
// Start with registering info about how the
// target lays out data structures.
- fpm.add(new llvm::TargetData(*executionEngine->getTargetData()));
+ fpm.add(new llvm::DataLayout(*executionEngine->getDataLayout()));
// Optimizations turned on
#ifdef ADD_OPT_PASSES
diff --git a/examples/Kaleidoscope/Chapter4/toy.cpp b/examples/Kaleidoscope/Chapter4/toy.cpp
index cce4466ed5..bc6028c900 100644
--- a/examples/Kaleidoscope/Chapter4/toy.cpp
+++ b/examples/Kaleidoscope/Chapter4/toy.cpp
@@ -7,7 +7,7 @@
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/TargetSelect.h"
#include <cstdio>
@@ -584,7 +584,7 @@ int main() {
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
- OurFPM.add(new TargetData(*TheExecutionEngine->getTargetData()));
+ OurFPM.add(new DataLayout(*TheExecutionEngine->getDataLayout()));
// Provide basic AliasAnalysis support for GVN.
OurFPM.add(createBasicAliasAnalysisPass());
// Do simple "peephole" optimizations and bit-twiddling optzns.
diff --git a/examples/Kaleidoscope/Chapter5/toy.cpp b/examples/Kaleidoscope/Chapter5/toy.cpp
index 36dd760e5f..2b0b9d54fe 100644
--- a/examples/Kaleidoscope/Chapter5/toy.cpp
+++ b/examples/Kaleidoscope/Chapter5/toy.cpp
@@ -7,7 +7,7 @@
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/TargetSelect.h"
#include <cstdio>
@@ -829,7 +829,7 @@ int main() {
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
- OurFPM.add(new TargetData(*TheExecutionEngine->getTargetData()));
+ OurFPM.add(new DataLayout(*TheExecutionEngine->getDataLayout()));
// Provide basic AliasAnalysis support for GVN.
OurFPM.add(createBasicAliasAnalysisPass());
// Do simple "peephole" optimizations and bit-twiddling optzns.
diff --git a/examples/Kaleidoscope/Chapter6/toy.cpp b/examples/Kaleidoscope/Chapter6/toy.cpp
index db3495dcc9..b751e3516b 100644
--- a/examples/Kaleidoscope/Chapter6/toy.cpp
+++ b/examples/Kaleidoscope/Chapter6/toy.cpp
@@ -7,7 +7,7 @@
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/TargetSelect.h"
#include <cstdio>
@@ -947,7 +947,7 @@ int main() {
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
- OurFPM.add(new TargetData(*TheExecutionEngine->getTargetData()));
+ OurFPM.add(new DataLayout(*TheExecutionEngine->getDataLayout()));
// Provide basic AliasAnalysis support for GVN.
OurFPM.add(createBasicAliasAnalysisPass());
// Do simple "peephole" optimizations and bit-twiddling optzns.
diff --git a/examples/Kaleidoscope/Chapter7/toy.cpp b/examples/Kaleidoscope/Chapter7/toy.cpp
index 143b30bf47..0ac0996590 100644
--- a/examples/Kaleidoscope/Chapter7/toy.cpp
+++ b/examples/Kaleidoscope/Chapter7/toy.cpp
@@ -7,7 +7,7 @@
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/Passes.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/TargetSelect.h"
#include <cstdio>
@@ -1111,7 +1111,7 @@ int main() {
// Set up the optimizer pipeline. Start with registering info about how the
// target lays out data structures.
- OurFPM.add(new TargetData(*TheExecutionEngine->getTargetData()));
+ OurFPM.add(new DataLayout(*TheExecutionEngine->getDataLayout()));
// Provide basic AliasAnalysis support for GVN.
OurFPM.add(createBasicAliasAnalysisPass());
// Promote allocas to registers.
diff --git a/examples/OCaml-Kaleidoscope/Chapter4/toy.ml b/examples/OCaml-Kaleidoscope/Chapter4/toy.ml
index 5f9d912499..5a6bde9458 100644
--- a/examples/OCaml-Kaleidoscope/Chapter4/toy.ml
+++ b/examples/OCaml-Kaleidoscope/Chapter4/toy.ml
@@ -27,7 +27,7 @@ let main () =
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
- TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
+ DataLayout.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
(* Do simple "peephole" optimizations and bit-twiddling optzn. *)
add_instruction_combination the_fpm;
diff --git a/examples/OCaml-Kaleidoscope/Chapter5/toy.ml b/examples/OCaml-Kaleidoscope/Chapter5/toy.ml
index 5f9d912499..5a6bde9458 100644
--- a/examples/OCaml-Kaleidoscope/Chapter5/toy.ml
+++ b/examples/OCaml-Kaleidoscope/Chapter5/toy.ml
@@ -27,7 +27,7 @@ let main () =
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
- TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
+ DataLayout.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
(* Do simple "peephole" optimizations and bit-twiddling optzn. *)
add_instruction_combination the_fpm;
diff --git a/examples/OCaml-Kaleidoscope/Chapter6/toy.ml b/examples/OCaml-Kaleidoscope/Chapter6/toy.ml
index 5f9d912499..5a6bde9458 100644
--- a/examples/OCaml-Kaleidoscope/Chapter6/toy.ml
+++ b/examples/OCaml-Kaleidoscope/Chapter6/toy.ml
@@ -27,7 +27,7 @@ let main () =
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
- TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
+ DataLayout.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
(* Do simple "peephole" optimizations and bit-twiddling optzn. *)
add_instruction_combination the_fpm;
diff --git a/examples/OCaml-Kaleidoscope/Chapter7/toy.ml b/examples/OCaml-Kaleidoscope/Chapter7/toy.ml
index babab28601..f2508a4357 100644
--- a/examples/OCaml-Kaleidoscope/Chapter7/toy.ml
+++ b/examples/OCaml-Kaleidoscope/Chapter7/toy.ml
@@ -28,7 +28,7 @@ let main () =
(* Set up the optimizer pipeline. Start with registering info about how the
* target lays out data structures. *)
- TargetData.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
+ DataLayout.add (ExecutionEngine.target_data the_execution_engine) the_fpm;
(* Promote allocas to registers. *)
add_memory_to_register_promotion the_fpm;
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h
index 4d3374958b..8cf03c268c 100644
--- a/include/llvm-c/Core.h
+++ b/include/llvm-c/Core.h
@@ -1803,7 +1803,7 @@ LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg);
* Set the alignment for a function parameter.
*
* @see llvm::Argument::addAttr()
- * @see llvm::Attribute::constructAlignmentFromInt()
+ * @see llvm::Attributes::constructAlignmentFromInt()
*/
void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align);
diff --git a/include/llvm-c/Target.h b/include/llvm-c/Target.h
index 89150401ff..92228701e3 100644
--- a/include/llvm-c/Target.h
+++ b/include/llvm-c/Target.h
@@ -145,7 +145,7 @@ static inline LLVMBool LLVMInitializeNativeTarget(void) {
/*===-- Target Data -------------------------------------------------------===*/
/** Creates target data from a target layout string.
- See the constructor llvm::TargetData::TargetData. */
+ See the constructor llvm::DataLayout::DataLayout. */
LLVMTargetDataRef LLVMCreateTargetData(const char *StringRep);
/** Adds target data information to a pass manager. This does not take ownership
@@ -160,48 +160,48 @@ void LLVMAddTargetLibraryInfo(LLVMTargetLibraryInfoRef, LLVMPassManagerRef);
/** Converts target data to a target layout string. The string must be disposed
with LLVMDisposeMessage.
- See the constructor llvm::TargetData::TargetData. */
+ See the constructor llvm::DataLayout::DataLayout. */
char *LLVMCopyStringRepOfTargetData(LLVMTargetDataRef);
/** Returns the byte order of a target, either LLVMBigEndian or
LLVMLittleEndian.
- See the method llvm::TargetData::isLittleEndian. */
+ See the method llvm::DataLayout::isLittleEndian. */
enum LLVMByteOrdering LLVMByteOrder(LLVMTargetDataRef);
/** Returns the pointer size in bytes for a target.
- See the method llvm::TargetData::getPointerSize. */
+ See the method llvm::DataLayout::getPointerSize. */
unsigned LLVMPointerSize(LLVMTargetDataRef);
/** Returns the integer type that is the same size as a pointer on a target.
- See the method llvm::TargetData::getIntPtrType. */
+ See the method llvm::DataLayout::getIntPtrType. */
LLVMTypeRef LLVMIntPtrType(LLVMTargetDataRef);
/** Computes the size of a type in bytes for a target.
- See the method llvm::TargetData::getTypeSizeInBits. */
+ See the method llvm::DataLayout::getTypeSizeInBits. */
unsigned long long LLVMSizeOfTypeInBits(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the storage size of a type in bytes for a target.
- See the method llvm::TargetData::getTypeStoreSize. */
+ See the method llvm::DataLayout::getTypeStoreSize. */
unsigned long long LLVMStoreSizeOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the ABI size of a type in bytes for a target.
- See the method llvm::TargetData::getTypeAllocSize. */
+ See the method llvm::DataLayout::getTypeAllocSize. */
unsigned long long LLVMABISizeOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the ABI alignment of a type in bytes for a target.
- See the method llvm::TargetData::getTypeABISize. */
+ See the method llvm::DataLayout::getTypeABISize. */
unsigned LLVMABIAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the call frame alignment of a type in bytes for a target.
- See the method llvm::TargetData::getTypeABISize. */
+ See the method llvm::DataLayout::getTypeABISize. */
unsigned LLVMCallFrameAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the preferred alignment of a type in bytes for a target.
- See the method llvm::TargetData::getTypeABISize. */
+ See the method llvm::DataLayout::getTypeABISize. */
unsigned LLVMPreferredAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
/** Computes the preferred alignment of a global variable in bytes for a target.
- See the method llvm::TargetData::getPreferredAlignment. */
+ See the method llvm::DataLayout::getPreferredAlignment. */
unsigned LLVMPreferredAlignmentOfGlobal(LLVMTargetDataRef,
LLVMValueRef GlobalVar);
@@ -216,7 +216,7 @@ unsigned long long LLVMOffsetOfElement(LLVMTargetDataRef, LLVMTypeRef StructTy,
unsigned Element);
/** Deallocates a TargetData.
- See the destructor llvm::TargetData::~TargetData. */
+ See the destructor llvm::DataLayout::~DataLayout. */
void LLVMDisposeTargetData(LLVMTargetDataRef);
/**
@@ -227,15 +227,15 @@ void LLVMDisposeTargetData(LLVMTargetDataRef);
}
namespace llvm {
- class TargetData;
+ class DataLayout;
class TargetLibraryInfo;
- inline TargetData *unwrap(LLVMTargetDataRef P) {
- return reinterpret_cast<TargetData*>(P);
+ inline DataLayout *unwrap(LLVMTargetDataRef P) {
+ return reinterpret_cast<DataLayout*>(P);
}
- inline LLVMTargetDataRef wrap(const TargetData *P) {
- return reinterpret_cast<LLVMTargetDataRef>(const_cast<TargetData*>(P));
+ inline LLVMTargetDataRef wrap(const DataLayout *P) {
+ return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout*>(P));
}
inline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) {
diff --git a/include/llvm-c/TargetMachine.h b/include/llvm-c/TargetMachine.h
index 0d35d73a11..29668de465 100644
--- a/include/llvm-c/TargetMachine.h
+++ b/include/llvm-c/TargetMachine.h
@@ -104,7 +104,7 @@ char *LLVMGetTargetMachineCPU(LLVMTargetMachineRef T);
LLVMDisposeMessage. */
char *LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T);
-/** Returns the llvm::TargetData used for this llvm:TargetMachine. */
+/** Returns the llvm::DataLayout used for this llvm:TargetMachine. */
LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T);
/** Emits an asm or object file for the given module to the filename. This
diff --git a/include/llvm/ADT/MapVector.h b/include/llvm/ADT/MapVector.h
index bad207baa9..3f7a596413 100644
--- a/include/llvm/ADT/MapVector.h
+++ b/include/llvm/ADT/MapVector.h
@@ -26,10 +26,10 @@ namespace llvm {
/// This class implements a map that also provides access to all stored values
/// in a deterministic order. The values are kept in a std::vector and the
/// mapping is done with DenseMap from Keys to indexes in that vector.
-template<typename KeyT, typename ValueT>
+template<typename KeyT, typename ValueT,
+ typename MapType = llvm::DenseMap<KeyT, unsigned>,
+ typename VectorType = std::vector<std::pair<KeyT, ValueT> > >
class MapVector {
- typedef llvm::DenseMap<KeyT, unsigned> MapType;
- typedef std::vector<std::pair<KeyT, ValueT> > VectorType;
typedef typename VectorType::size_type SizeType;
MapType Map;
@@ -63,6 +63,11 @@ public:
return Vector.empty();
}
+ void clear() {
+ Map.clear();
+ Vector.clear();
+ }
+
ValueT &operator[](const KeyT &Key) {
std::pair<KeyT, unsigned> Pair = std::make_pair(Key, 0);
std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
diff --git a/include/llvm/ADT/SetVector.h b/include/llvm/ADT/SetVector.h
index 965f0deaca..d2f7286c25 100644
--- a/include/llvm/ADT/SetVector.h
+++ b/include/llvm/ADT/SetVector.h
@@ -27,10 +27,11 @@
namespace llvm {
+/// \brief A vector that has set insertion semantics.
+///
/// This adapter class provides a way to keep a set of things that also has the
/// property of a deterministic iteration order. The order of iteration is the
/// order of insertion.
-/// @brief A vector that has set insertion semantics.
template <typename T, typename Vector = std::vector<T>,
typename Set = SmallSet<T, 16> >
class SetVector {
@@ -45,59 +46,59 @@ public:
typedef typename vector_type::const_iterator const_iterator;
typedef typename vector_type::size_type size_type;
- /// @brief Construct an empty SetVector
+ /// \brief Construct an empty SetVector
SetVector() {}
- /// @brief Initialize a SetVector with a range of elements
+ /// \brief Initialize a SetVector with a range of elements
template<typename It>
SetVector(It Start, It End) {
insert(Start, End);
}
- /// @brief Determine if the SetVector is empty or not.
+ /// \brief Determine if the SetVector is empty or not.
bool empty() const {
return vector_.empty();
}
- /// @brief Determine the number of elements in the SetVector.
+ /// \brief Determine the number of elements in the SetVector.
size_type size() const {
return vector_.size();
}
- /// @brief Get an iterator to the beginning of the SetVector.
+ /// \brief Get an iterator to the beginning of the SetVector.
iterator begin() {
return vector_.begin();
}
- /// @brief Get a const_iterator to the beginning of the SetVector.
+ /// \brief Get a const_iterator to the beginning of the SetVector.
const_iterator begin() const {
return vector_.begin();
}
- /// @brief Get an iterator to the end of the SetVector.
+ /// \brief Get an iterator to the end of the SetVector.
iterator end() {
return vector_.end();
}
- /// @brief Get a const_iterator to the end of the SetVector.
+ /// \brief Get a const_iterator to the end of the SetVector.
const_iterator end() const {
return vector_.end();
}
- /// @brief Return the last element of the SetVector.
+ /// \brief Return the last element of the SetVector.
const T &back() const {
assert(!empty() && "Cannot call back() on empty SetVector!");
return vector_.back();
}
- /// @brief Index into the SetVector.
+ /// \brief Index into the SetVector.
const_reference operator[](size_type n) const {
assert(n < vector_.size() && "SetVector access out of range!");
return vector_[n];
}
- /// @returns true iff the element was inserted into the SetVector.
- /// @brief Insert a new element into the SetVector.
+ /// \brief Insert a new element into the SetVector.
+ /// \returns true iff the element was inserted into the SetVector.
bool insert(const value_type &X) {
bool result = set_.insert(X);
if (result)
@@ -105,7 +106,7 @@ public:
return result;
}
- /// @brief Insert a range of elements into the SetVector.
+ /// \brief Insert a range of elements into the SetVector.
template<typename It>
void insert(It Start, It End) {
for (; Start != End; ++Start)
@@ -113,7 +114,7 @@ public:
vector_.push_back(*Start);
}
- /// @brief Remove an item from the set vector.
+ /// \brief Remove an item from the set vector.
bool remove(const value_type& X) {
if (set_.erase(X)) {
typename vector_type::iterator I =
@@ -125,20 +126,44 @@ public:
return false;
}
-
- /// @returns 0 if the element is not in the SetVector, 1 if it is.
- /// @brief Count the number of elements of a given key in the SetVector.
+ /// \brief Remove items from the set vector based on a predicate function.
+ ///
+ /// This is intended to be equivalent to the following code, if we could
+ /// write it:
+ ///
+ /// \code
+ /// V.erase(std::remove_if(V.begin(), V.end(), P), V.end());
+ /// \endcode
+ ///
+ /// However, SetVector doesn't expose non-const iterators, making any
+ /// algorithm like remove_if impossible to use.
+ ///
+ /// \returns true if any element is removed.
+ template <typename UnaryPredicate>
+ bool remove_if(UnaryPredicate P) {
+ typename vector_type::iterator I
+ = std::remove_if(vector_.begin(), vector_.end(),
+ TestAndEraseFromSet<UnaryPredicate>(P, set_));
+ if (I == vector_.end())
+ return false;
+ vector_.erase(I, vector_.end());
+ return true;
+ }
+
+
+ /// \brief Count the number of elements of a given key in the SetVector.
+ /// \returns 0 if the element is not in the SetVector, 1 if it is.
size_type count(const key_type &key) const {
return set_.count(key);
}
- /// @brief Completely clear the SetVector
+ /// \brief Completely clear the SetVector
void clear() {
set_.clear();
vector_.clear();
}
- /// @brief Remove the last element of the SetVector.
+ /// \brief Remove the last element of the SetVector.
void pop_back() {
assert(!empty() && "Cannot remove an element from an empty SetVector!");
set_.erase(back());
@@ -160,18 +185,41 @@ public:
}
private:
+ /// \brief A wrapper predicate designed for use with std::remove_if.
+ ///
+ /// This predicate wraps a predicate suitable for use with std::remove_if to
+ /// call set_.erase(x) on each element which is slated for removal.
+ template <typename UnaryPredicate>
+ class TestAndEraseFromSet {
+ UnaryPredicate P;
+ set_type &set_;
+
+ public:
+ typedef typename UnaryPredicate::argument_type argument_type;
+
+ TestAndEraseFromSet(UnaryPredicate P, set_type &set_) : P(P), set_(set_) {}
+
+ bool operator()(argument_type Arg) {
+ if (P(Arg)) {
+ set_.erase(Arg);
+ return true;
+ }
+ return false;
+ }
+ };
+
set_type set_; ///< The set.
vector_type vector_; ///< The vector.
};
-/// SmallSetVector - A SetVector that performs no allocations if smaller than
+/// \brief A SetVector that performs no allocations if smaller than
/// a certain size.
template <typename T, unsigned N>
class SmallSetVector : public SetVector<T, SmallVector<T, N>, SmallSet<T, N> > {
public:
SmallSetVector() {}
- /// @brief Initialize a SmallSetVector with a range of elements
+ /// \brief Initialize a SmallSetVector with a range of elements
template<typename It>
SmallSetVector(It Start, It End) {
this->insert(Start, End);
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index f701a793af..a0527683f6 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -65,7 +65,8 @@ public:
nvptx, // NVPTX: 32-bit
nvptx64, // NVPTX: 64-bit
le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
- amdil // amdil: amd IL
+ amdil, // amdil: amd IL
+ spir // SPIR: standard portable IR for OpenCL
};
enum VendorType {
UnknownVendor,
@@ -110,7 +111,8 @@ public:
GNUEABIHF,
EABI,
MachO,
- Android
+ Android,
+ ELF
};
private:
diff --git a/include/llvm/AddressingMode.h b/include/llvm/AddressingMode.h
new file mode 100644
index 0000000000..70b3c05238
--- /dev/null
+++ b/include/llvm/AddressingMode.h
@@ -0,0 +1,41 @@
+//===--------- llvm/AddressingMode.h - Addressing Mode -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This file contains addressing mode data structures which are shared
+// between LSR and a number of places in the codegen.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADDRESSING_MODE_H
+#define LLVM_ADDRESSING_MODE_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class GlobalValue;
+
+/// AddrMode - This represents an addressing mode of:
+/// BaseGV + BaseOffs + BaseReg + Scale*ScaleReg
+/// If BaseGV is null, there is no BaseGV.
+/// If BaseOffs is zero, there is no base offset.
+/// If HasBaseReg is false, there is no base register.
+/// If Scale is zero, there is no ScaleReg. Scale of 1 indicates a reg with
+/// no scale.
+///
+struct AddrMode {
+ GlobalValue *BaseGV;
+ int64_t BaseOffs;
+ bool HasBaseReg;
+ int64_t Scale;
+ AddrMode() : BaseGV(0), BaseOffs(0), HasBaseReg(false), Scale(0) {}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h
index f5872201ad..be274afd15 100644
--- a/include/llvm/Analysis/AliasAnalysis.h
+++ b/include/llvm/Analysis/AliasAnalysis.h
@@ -45,7 +45,7 @@ namespace llvm {
class LoadInst;
class StoreInst;
class VAArgInst;
-class TargetData;
+class DataLayout;
class TargetLibraryInfo;
class Pass;
class AnalysisUsage;
@@ -55,7 +55,7 @@ class DominatorTree;
class AliasAnalysis {
protected:
- const TargetData *TD;
+ const DataLayout *TD;
const TargetLibraryInfo *TLI;
private:
@@ -83,17 +83,17 @@ public:
/// know the sizes of the potential memory references.
static uint64_t const UnknownSize = ~UINT64_C(0);
- /// getTargetData - Return a pointer to the current TargetData object, or
- /// null if no TargetData object is available.
+ /// getDataLayout - Return a pointer to the current DataLayout object, or
+ /// null if no DataLayout object is available.
///
- const TargetData *getTargetData() const { return TD; }
+ const DataLayout *getDataLayout() const { return TD; }
/// getTargetLibraryInfo - Return a pointer to the current TargetLibraryInfo
/// object, or null if no TargetLibraryInfo object is available.
///
const TargetLibraryInfo *getTargetLibraryInfo() const { return TLI; }
- /// getTypeStoreSize - Return the TargetData store size for the given type,
+ /// getTypeStoreSize - Return the DataLayout store size for the given type,
/// if known, or a conservative value otherwise.
///
uint64_t getTypeStoreSize(Type *Ty);
diff --git a/include/llvm/Analysis/CaptureTracking.h b/include/llvm/Analysis/CaptureTracking.h
index 9b5e8425ad..2889269b95 100644
--- a/include/llvm/Analysis/CaptureTracking.h
+++ b/include/llvm/Analysis/CaptureTracking.h
@@ -46,7 +46,7 @@ namespace llvm {
/// capture) return false. To search it, return true.
///
/// U->getUser() is always an Instruction.
- virtual bool shouldExplore(Use *U) = 0;
+ virtual bool shouldExplore(Use *U);
/// captured - Information about the pointer was captured by the user of
/// use U. Return true to stop the traversal or false to continue looking
diff --git a/include/llvm/Analysis/CodeMetrics.h b/include/llvm/Analysis/CodeMetrics.h
index 03c807cf83..4398faa20a 100644
--- a/include/llvm/Analysis/CodeMetrics.h
+++ b/include/llvm/Analysis/CodeMetrics.h
@@ -22,11 +22,11 @@ namespace llvm {
class BasicBlock;
class Function;
class Instruction;
- class TargetData;
+ class DataLayout;
class Value;
/// \brief Check whether an instruction is likely to be "free" when lowered.
- bool isInstructionFree(const Instruction *I, const TargetData *TD = 0);
+ bool isInstructionFree(const Instruction *I, const DataLayout *TD = 0);
/// \brief Check whether a call will lower to something small.
///
@@ -85,10 +85,10 @@ namespace llvm {
NumRets(0) {}
/// \brief Add information about a block to the current state.
- void analyzeBasicBlock(const BasicBlock *BB, const TargetData *TD = 0);
+ void analyzeBasicBlock(const BasicBlock *BB, const DataLayout *TD = 0);
/// \brief Add information about a function to the current state.
- void analyzeFunction(Function *F, const TargetData *TD = 0);
+ void analyzeFunction(Function *F, const DataLayout *TD = 0);
};
}
diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h
index 2fdef5f083..12e623ea9b 100644
--- a/include/llvm/Analysis/ConstantFolding.h
+++ b/include/llvm/Analysis/ConstantFolding.h
@@ -12,7 +12,7 @@
//
// Also, to supplement the basic VMCore ConstantExpr simplifications,
// this file declares some additional folding routines that can make use of
-// TargetData information. These functions cannot go in VMCore due to library
+// DataLayout information. These functions cannot go in VMCore due to library
// dependency issues.
//
//===----------------------------------------------------------------------===//
@@ -24,7 +24,7 @@ namespace llvm {
class Constant;
class ConstantExpr;
class Instruction;
- class TargetData;
+ class DataLayout;
class TargetLibraryInfo;
class Function;
class Type;
@@ -36,14 +36,14 @@ namespace llvm {
/// Note that this fails if not all of the operands are constant. Otherwise,
/// this function can only fail when attempting to fold instructions like loads
/// and stores, which have no constant expression form.
-Constant *ConstantFoldInstruction(Instruction *I, const TargetData *TD = 0,
+Constant *ConstantFoldInstruction(Instruction *I, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldConstantExpression - Attempt to fold the constant expression
-/// using the specified TargetData. If successful, the constant result is
+/// using the specified DataLayout. If successful, the constant result is
/// result is returned, if not, null is returned.
Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
@@ -54,7 +54,7 @@ Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
///
Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
ArrayRef<Constant *> Ops,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldCompareInstOperands - Attempt to constant fold a compare
@@ -63,7 +63,7 @@ Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
///
Constant *ConstantFoldCompareInstOperands(unsigned Predicate,
Constant *LHS, Constant *RHS,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue
@@ -75,7 +75,7 @@ Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val,
/// ConstantFoldLoadFromConstPtr - Return the value that a load from C would
/// produce if it is constant and determinable. If this is not determinable,
/// return null.
-Constant *ConstantFoldLoadFromConstPtr(Constant *C, const TargetData *TD = 0);
+Constant *ConstantFoldLoadFromConstPtr(Constant *C, const DataLayout *TD = 0);
/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a
/// getelementptr constantexpr, return the constant value being addressed by the
diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h
index a1cc196eae..8940971558 100644
--- a/include/llvm/Analysis/Dominators.h
+++ b/include/llvm/Analysis/Dominators.h
@@ -346,7 +346,7 @@ public:
DomTreeNodeBase<NodeT> *getRootNode() { return RootNode; }
const DomTreeNodeBase<NodeT> *getRootNode() const { return RootNode; }
- /// properlyDominates - Returns true iff this dominates N and this != N.
+ /// properlyDominates - Returns true iff A dominates B and A != B.
/// Note that this is not a constant time operation!
///
bool properlyDominates(const DomTreeNodeBase<NodeT> *A,
diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h
index 2bf79b9c93..9b98013a16 100644
--- a/include/llvm/Analysis/IVUsers.h
+++ b/include/llvm/Analysis/IVUsers.h
@@ -28,7 +28,7 @@ class IVUsers;
class ScalarEvolution;
class SCEV;
class IVUsers;
-class TargetData;
+class DataLayout;
/// IVStrideUse - Keep track of one use of a strided induction variable.
/// The Expr member keeps track of the expression, User is the actual user
@@ -123,7 +123,7 @@ class IVUsers : public LoopPass {
LoopInfo *LI;
DominatorTree *DT;
ScalarEvolution *SE;
- TargetData *TD;
+ DataLayout *TD;
SmallPtrSet<Instruction*,16> Processed;
/// IVUses - A list of all tracked IV uses of induction variable expressions
diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h
index d58671f873..a075db3342 100644
--- a/include/llvm/Analysis/InlineCost.h
+++ b/include/llvm/Analysis/InlineCost.h
@@ -26,7 +26,7 @@
namespace llvm {
class CallSite;
- class TargetData;
+ class DataLayout;
namespace InlineConstants {
// Various magic constants used to adjust heuristics.
@@ -104,13 +104,13 @@ namespace llvm {
/// InlineCostAnalyzer - Cost analyzer used by inliner.
class InlineCostAnalyzer {
- // TargetData if available, or null.
- const TargetData *TD;
+ // DataLayout if available, or null.
+ const DataLayout *TD;
public:
InlineCostAnalyzer(): TD(0) {}
- void setTargetData(const TargetData *TData) { TD = TData; }
+ void setDataLayout(const DataLayout *TData) { TD = TData; }
/// \brief Get an InlineCost object representing the cost of inlining this
/// callsite.
diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h
index 152e885bf6..e561e3742b 100644
--- a/include/llvm/Analysis/InstructionSimplify.h
+++ b/include/llvm/Analysis/InstructionSimplify.h
@@ -24,7 +24,7 @@ namespace llvm {
class ArrayRef;
class DominatorTree;
class Instruction;
- class TargetData;
+ class DataLayout;
class TargetLibraryInfo;
class Type;
class Value;
@@ -32,122 +32,122 @@ namespace llvm {
/// SimplifyAddInst - Given operands for an Add, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySubInst - Given operands for a Sub, see if we can
/// fold the result. If not, this returns null.
Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyMulInst - Given operands for a Mul, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyMulInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySDivInst - Given operands for an SDiv, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifySDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifySDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyUDivInst - Given operands for a UDiv, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyUDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyFDivInst - Given operands for an FDiv, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyFDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifyFDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySRemInst - Given operands for an SRem, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifySRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyURemInst - Given operands for a URem, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyURemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifyURemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyFRemInst - Given operands for an FRem, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyFRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifyFRemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyShlInst - Given operands for a Shl, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyLShrInst - Given operands for a LShr, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyAShrInst - Given operands for a AShr, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyAndInst - Given operands for an And, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyAndInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifyAndInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyOrInst - Given operands for an Or, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyOrInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifyOrInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyXorInst - Given operands for a Xor, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyXorInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
+ Value *SimplifyXorInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySelectInst - Given operands for a SelectInst, see if we can fold
/// the result. If not, this returns null.
Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const TargetData *TD = 0,
+ Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@@ -155,13 +155,13 @@ namespace llvm {
/// can fold the result. If not, this returns null.
Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
ArrayRef<unsigned> Idxs,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyTruncInst - Given operands for an TruncInst, see if we can fold
/// the result. If not, this returns null.
- Value *SimplifyTruncInst(Value *Op, Type *Ty, const TargetData *TD = 0,
+ Value *SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@@ -171,20 +171,20 @@ namespace llvm {
/// SimplifyCmpInst - Given operands for a CmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyInstruction - See if we can compute a simplified version of this
/// instruction. If not, this returns null.
- Value *SimplifyInstruction(Instruction *I, const TargetData *TD = 0,
+ Value *SimplifyInstruction(Instruction *I, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@@ -198,7 +198,7 @@ namespace llvm {
///
/// The function returns true if any simplifications were performed.
bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
@@ -209,7 +209,7 @@ namespace llvm {
/// of the users impacted. It returns true if any simplifications were
/// performed.
bool recursivelySimplifyInstruction(Instruction *I,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
} // end namespace llvm
diff --git a/include/llvm/Analysis/LazyValueInfo.h b/include/llvm/Analysis/LazyValueInfo.h
index 7b887d5a9a..197e94e5fd 100644
--- a/include/llvm/Analysis/LazyValueInfo.h
+++ b/include/llvm/Analysis/LazyValueInfo.h
@@ -19,14 +19,14 @@
namespace llvm {
class Constant;
- class TargetData;
+ class DataLayout;
class TargetLibraryInfo;
class Value;
/// LazyValueInfo - This pass computes, caches, and vends lazy value constraint
/// information.
class LazyValueInfo : public FunctionPass {
- class TargetData *TD;
+ class DataLayout *TD;
class TargetLibraryInfo *TLI;
void *PImpl;
LazyValueInfo(const LazyValueInfo&) LLVM_DELETED_FUNCTION;
diff --git a/include/llvm/Analysis/Loads.h b/include/llvm/Analysis/Loads.h
index 5f0aefbeb0..afc90c2f74 100644
--- a/include/llvm/Analysis/Loads.h
+++ b/include/llvm/Analysis/Loads.h
@@ -19,7 +19,7 @@
namespace llvm {
class AliasAnalysis;
-class TargetData;
+class DataLayout;
class MDNode;
/// isSafeToLoadUnconditionally - Return true if we know that executing a load
@@ -27,7 +27,7 @@ class MDNode;
/// specified pointer, we do a quick local scan of the basic block containing
/// ScanFrom, to determine if the address is already accessed.
bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom,
- unsigned Align, const TargetData *TD = 0);
+ unsigned Align, const DataLayout *TD = 0);
/// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at
/// the instruction before ScanFrom) checking to see if we have the value at
diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h
index c3ae603b70..a842898e41 100644
--- a/include/llvm/Analysis/MemoryBuiltins.h
+++ b/include/llvm/Analysis/MemoryBuiltins.h
@@ -27,7 +27,7 @@
namespace llvm {
class CallInst;
class PointerType;
-class TargetData;
+class DataLayout;
class TargetLibraryInfo;
class Type;
class Value;
@@ -81,7 +81,7 @@ static inline CallInst *extractMallocCall(Value *I,
/// isArrayMalloc - Returns the corresponding CallInst if the instruction
/// is a call to malloc whose array size can be determined and the array size
/// is not constant 1. Otherwise, return NULL.
-const CallInst *isArrayMalloc(const Value *I, const TargetData *TD,
+const CallInst *isArrayMalloc(const Value *I, const DataLayout *TD,
const TargetLibraryInfo *TLI);
/// getMallocType - Returns the PointerType resulting from the malloc call.
@@ -103,7 +103,7 @@ Type *getMallocAllocatedType(const CallInst *CI, const TargetLibraryInfo *TLI);
/// then return that multiple. For non-array mallocs, the multiple is
/// constant 1. Otherwise, return NULL for mallocs whose array size cannot be
/// determined.
-Value *getMallocArraySize(CallInst *CI, const TargetData *TD,
+Value *getMallocArraySize(CallInst *CI, const DataLayout *TD,
const TargetLibraryInfo *TLI,
bool LookThroughSExt = false);
@@ -141,7 +141,7 @@ static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) {
/// object size in Size if successful, and false otherwise.
/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
/// byval arguments, and global variables.
-bool getObjectSize(const Value *Ptr, uint64_t &Size, const TargetData *TD,
+bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD,
const TargetLibraryInfo *TLI, bool RoundToAlign = false);
@@ -153,7 +153,7 @@ typedef std::pair<APInt, APInt> SizeOffsetType;
class ObjectSizeOffsetVisitor
: public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> {
- const TargetData *TD;
+ const DataLayout *TD;
const TargetLibraryInfo *TLI;
bool RoundToAlign;
unsigned IntTyBits;
@@ -167,7 +167,7 @@ class ObjectSizeOffsetVisitor
}
public:
- ObjectSizeOffsetVisitor(const TargetData *TD, const TargetLibraryInfo *TLI,
+ ObjectSizeOffsetVisitor(const DataLayout *TD, const TargetLibraryInfo *TLI,
LLVMContext &Context, bool RoundToAlign = false);
SizeOffsetType compute(Value *V);
@@ -213,7 +213,7 @@ class ObjectSizeOffsetEvaluator
typedef DenseMap<const Value*, WeakEvalType> CacheMapTy;
typedef SmallPtrSet<const Value*, 8> PtrSetTy;
- const TargetData *TD;
+ const DataLayout *TD;
const TargetLibraryInfo *TLI;
LLVMContext &Context;
BuilderTy Builder;
@@ -228,7 +228,7 @@ class ObjectSizeOffsetEvaluator
SizeOffsetEvalType compute_(Value *V);
public:
- ObjectSizeOffsetEvaluator(const TargetData *TD, const TargetLibraryInfo *TLI,
+ ObjectSizeOffsetEvaluator(const DataLayout *TD, const TargetLibraryInfo *TLI,
LLVMContext &Context);
SizeOffsetEvalType compute(Value *V);
diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h
index 7e049d633b..a715eaeee1 100644
--- a/include/llvm/Analysis/MemoryDependenceAnalysis.h
+++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h
@@ -29,7 +29,7 @@ namespace llvm {
class Instruction;
class CallSite;
class AliasAnalysis;
- class TargetData;
+ class DataLayout;
class MemoryDependenceAnalysis;
class PredIteratorCache;
class DominatorTree;
@@ -323,7 +323,7 @@ namespace llvm {
/// Current AA implementation, just a cache.
AliasAnalysis *AA;
- TargetData *TD;
+ DataLayout *TD;
DominatorTree *DT;
OwningPtr<PredIteratorCache> PredCache;
public:
@@ -412,7 +412,7 @@ namespace llvm {
int64_t MemLocOffs,
unsigned MemLocSize,
const LoadInst *LI,
- const TargetData &TD);
+ const DataLayout &TD);
private:
MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,
diff --git a/include/llvm/Analysis/PHITransAddr.h b/include/llvm/Analysis/PHITransAddr.h
index ff9a24790a..5a77fcebaf 100644
--- a/include/llvm/Analysis/PHITransAddr.h
+++ b/include/llvm/Analysis/PHITransAddr.h
@@ -19,7 +19,7 @@
namespace llvm {
class DominatorTree;
- class TargetData;
+ class DataLayout;
class TargetLibraryInfo;
/// PHITransAddr - An address value which tracks and handles phi translation.
@@ -37,7 +37,7 @@ class PHITransAddr {
Value *Addr;
/// TD - The target data we are playing with if known, otherwise null.
- const TargetData *TD;
+ const DataLayout *TD;
/// TLI - The target library info if known, otherwise null.
const TargetLibraryInfo *TLI;
@@ -45,7 +45,7 @@ class PHITransAddr {
/// InstInputs - The inputs for our symbolic address.
SmallVector<Instruction*, 4> InstInputs;
public:
- PHITransAddr(Value *addr, const TargetData *td) : Addr(addr), TD(td), TLI(0) {
+ PHITransAddr(Value *addr, const DataLayout *td) : Addr(addr), TD(td), TLI(0) {
// If the address is an instruction, the whole thing is considered an input.
if (Instruction *I = dyn_cast<Instruction>(Addr))
InstInputs.push_back(I);
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
index c8c249a1b1..a055195352 100644
--- a/include/llvm/Analysis/ScalarEvolution.h
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -40,7 +40,7 @@ namespace llvm {
class DominatorTree;
class Type;
class ScalarEvolution;
- class TargetData;
+ class DataLayout;
class TargetLibraryInfo;
class LLVMContext;
class Loop;
@@ -227,7 +227,7 @@ namespace llvm {
/// TD - The target data information for the target we are targeting.
///
- TargetData *TD;
+ DataLayout *TD;
/// TLI - The target library information for the target we are targeting.
///
diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h
index e8d45f6bb8..a85752446b 100644
--- a/include/llvm/Analysis/ValueTracking.h
+++ b/include/llvm/Analysis/ValueTracking.h
@@ -22,7 +22,7 @@ namespace llvm {
class Value;
class Instruction;
class APInt;
- class TargetData;
+ class DataLayout;
class StringRef;
class MDNode;
@@ -37,27 +37,27 @@ namespace llvm {
/// same width as the vector element, and the bit is set only if it is true
/// for all of the elements in the vector.
void ComputeMaskedBits(Value *V, APInt &KnownZero, APInt &KnownOne,
- const TargetData *TD = 0, unsigned Depth = 0);
+ const DataLayout *TD = 0, unsigned Depth = 0);
void computeMaskedBitsLoad(const MDNode &Ranges, APInt &KnownZero);
/// ComputeSignBit - Determine whether the sign bit is known to be zero or
/// one. Convenience wrapper around ComputeMaskedBits.
void ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne,
- const TargetData *TD = 0, unsigned Depth = 0);
+ const DataLayout *TD = 0, unsigned Depth = 0);
/// isPowerOfTwo - Return true if the given value is known to have exactly one
/// bit set when defined. For vectors return true if every element is known to
/// be a power of two when defined. Supports values with integer or pointer
/// type and vectors of integers. If 'OrZero' is set then returns true if the
/// given value is either a power of two or zero.
- bool isPowerOfTwo(Value *V, const TargetData *TD = 0, bool OrZero = false,
+ bool isPowerOfTwo(Value *V, const DataLayout *TD = 0, bool OrZero = false,
unsigned Depth = 0);
/// isKnownNonZero - Return true if the given value is known to be non-zero
/// when defined. For vectors return true if every element is known to be
/// non-zero when defined. Supports values with integer or pointer type and
/// vectors of integers.
- bool isKnownNonZero(Value *V, const TargetData *TD = 0, unsigned Depth = 0);
+ bool isKnownNonZero(Value *V, const DataLayout *TD = 0, unsigned Depth = 0);
/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use
/// this predicate to simplify operations downstream. Mask is known to be
@@ -69,7 +69,7 @@ namespace llvm {
/// same width as the vector element, and the bit is set only if it is true
/// for all of the elements in the vector.
bool MaskedValueIsZero(Value *V, const APInt &Mask,
- const TargetData *TD = 0, unsigned Depth = 0);
+ const DataLayout *TD = 0, unsigned Depth = 0);
/// ComputeNumSignBits - Return the number of times the sign bit of the
@@ -80,7 +80,7 @@ namespace llvm {
///
/// 'Op' must have a scalar integer type.
///
- unsigned ComputeNumSignBits(Value *Op, const TargetData *TD = 0,
+ unsigned ComputeNumSignBits(Value *Op, const DataLayout *TD = 0,
unsigned Depth = 0);
/// ComputeMultiple - This function computes the integer multiple of Base that
@@ -118,10 +118,10 @@ namespace llvm {
/// it can be expressed as a base pointer plus a constant offset. Return the
/// base and offset to the caller.
Value *GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset,
- const TargetData &TD);
+ const DataLayout &TD);
static inline const Value *
GetPointerBaseWithConstantOffset(const Value *Ptr, int64_t &Offset,
- const TargetData &TD) {
+ const DataLayout &TD) {
return GetPointerBaseWithConstantOffset(const_cast<Value*>(Ptr), Offset,TD);
}
@@ -143,10 +143,10 @@ namespace llvm {
/// being addressed. Note that the returned value has pointer type if the
/// specified value does. If the MaxLookup value is non-zero, it limits the
/// number of instructions to be stripped off.
- Value *GetUnderlyingObject(Value *V, const TargetData *TD = 0,
+ Value *GetUnderlyingObject(Value *V, const DataLayout *TD = 0,
unsigned MaxLookup = 6);
static inline const Value *
- GetUnderlyingObject(const Value *V, const TargetData *TD = 0,
+ GetUnderlyingObject(const Value *V, const DataLayout *TD = 0,
unsigned MaxLookup = 6) {
return GetUnderlyingObject(const_cast<Value *>(V), TD, MaxLookup);
}
@@ -156,7 +156,7 @@ namespace llvm {
/// multiple objects.
void GetUnderlyingObjects(Value *V,
SmallVectorImpl<Value *> &Objects,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
unsigned MaxLookup = 6);
/// onlyUsedByLifetimeMarkers - Return true if the only users of this pointer
@@ -182,7 +182,7 @@ namespace llvm {
/// However, this method can return true for instructions that read memory;
/// for such instructions, moving them may change the resulting value.
bool isSafeToSpeculativelyExecute(const Value *V,
- const TargetData *TD = 0);
+ const DataLayout *TD = 0);
} // end namespace llvm
diff --git a/include/llvm/Argument.h b/include/llvm/Argument.h
index e66075c1f2..1155b974ec 100644
--- a/include/llvm/Argument.h
+++ b/include/llvm/Argument.h
@@ -68,8 +68,8 @@ public:
/// attribute on it in its containing function.
bool hasNoCaptureAttr() const;
- /// hasSRetAttr - Return true if this argument has the sret attribute on it in
- /// its containing function.
+ /// hasStructRetAttr - Return true if this argument has the sret attribute on
+ /// it in its containing function.
bool hasStructRetAttr() const;
/// addAttr - Add a Attribute to an argument
diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h
index c9589603f9..1c2770995c 100644
--- a/include/llvm/Attributes.h
+++ b/include/llvm/Attributes.h
@@ -15,6 +15,7 @@
#ifndef LLVM_ATTRIBUTES_H
#define LLVM_ATTRIBUTES_H
+#include "llvm/AttributesImpl.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/ADT/ArrayRef.h"
#include <cassert>
@@ -27,8 +28,8 @@ class Type;
namespace Attribute {
-/// We use this proxy POD type to allow constructing Attributes constants using
-/// initializer lists. Do not use this class directly.
+/// AttrConst - We use this proxy POD type to allow constructing Attributes
+/// constants using initializer lists. Do not use this class directly.
struct AttrConst {
uint64_t v;
AttrConst operator | (const AttrConst Attrs) const {
@@ -52,7 +53,6 @@ struct AttrConst {
/// declarations. This is done to avoid static CTORs and at the same time to
/// keep type-safety of Attributes.
#define DECLARE_LLVM_ATTRIBUTE(name, value) \
- const uint64_t name##_i = value; \
const AttrConst name = {value};
DECLARE_LLVM_ATTRIBUTE(None,0) ///< No attributes have been set
@@ -109,30 +109,6 @@ DECLARE_LLVM_ATTRIBUTE(AddressSafety,1ULL<<32) ///< Address safety checking is o
/// an exception might pass by.
/// uwtable + nounwind = Needs an entry because the ABI says so.
-/// @brief Attributes that only apply to function parameters.
-const AttrConst ParameterOnly = {ByVal_i | Nest_i |
- StructRet_i | NoCapture_i};
-
-/// @brief Attributes that may be applied to the function itself. These cannot
-/// be used on return values or function parameters.
-const AttrConst FunctionOnly = {NoReturn_i | NoUnwind_i | ReadNone_i |
- ReadOnly_i | NoInline_i | AlwaysInline_i | OptimizeForSize_i |
- StackProtect_i | StackProtectReq_i | NoRedZone_i | NoImplicitFloat_i |
- Naked_i | InlineHint_i | StackAlignment_i |
- UWTable_i | NonLazyBind_i | ReturnsTwice_i | AddressSafety_i};
-
-/// @brief Parameter attributes that do not apply to vararg call arguments.
-const AttrConst VarArgsIncompatible = {StructRet_i};
-
-/// @brief Attributes that are mutually incompatible.
-const AttrConst MutuallyIncompatible[5] = {
- {ByVal_i | Nest_i | StructRet_i},
- {ByVal_i | Nest_i | InReg_i },
- {ZExt_i | SExt_i},
- {ReadNone_i | ReadOnly_i},
- {NoInline_i | AlwaysInline_i}
-};
-
} // namespace Attribute
/// AttributeImpl - The internal representation of the Attributes class. This is
@@ -141,271 +117,197 @@ class AttributesImpl;
/// Attributes - A bitset of attributes.
class Attributes {
- // Currently, we need less than 64 bits.
- uint64_t Bits;
+public:
+ enum AttrVal {
+ None = 0, ///< No attributes have been set
+ AddressSafety = 1, ///< Address safety checking is on.
+ Alignment = 2, ///< Alignment of parameter (5 bits)
+ ///< stored as log2 of alignment with +1 bias
+ ///< 0 means unaligned different from align 1
+ AlwaysInline = 3, ///< inline=always
+ ByVal = 4, ///< Pass structure by value
+ InlineHint = 5, ///< Source said inlining was desirable
+ InReg = 6, ///< Force argument to be passed in register
+ Naked = 7, ///< Naked function
+ Nest = 8, ///< Nested function static chain
+ NoAlias = 9, ///< Considered to not alias after call
+ NoCapture = 10, ///< Function creates no aliases of pointer
+ NoImplicitFloat = 11, ///< Disable implicit floating point insts
+ NoInline = 12, ///< inline=never
+ NonLazyBind = 13, ///< Function is called early and/or
+ ///< often, so lazy binding isn't worthwhile
+ NoRedZone = 14, ///< Disable redzone
+ NoReturn = 15, ///< Mark the function as not returning
+ NoUnwind = 16, ///< Function doesn't unwind stack
+ OptimizeForSize = 17, ///< opt_size
+ ReadNone = 18, ///< Function does not access memory
+ ReadOnly = 19, ///< Function only reads from memory
+ ReturnsTwice = 20, ///< Function can return twice
+ SExt = 21, ///< Sign extended before/after call
+ StackAlignment = 22, ///< Alignment of stack for function (3 bits)
+ ///< stored as log2 of alignment with +1 bias 0
+ ///< means unaligned (different from
+ ///< alignstack={1))
+ StackProtect = 23, ///< Stack protection.
+ StackProtectReq = 24, ///< Stack protection required.
+ StructRet = 25, ///< Hidden pointer to structure to return
+ UWTable = 26, ///< Function must be in a unwind table
+ ZExt = 27 ///< Zero extended before/after call
+ };
+private:
+ AttributesImpl Attrs;
explicit Attributes(AttributesImpl *A);
public:
- Attributes() : Bits(0) {}
- explicit Attributes(uint64_t Val) : Bits(Val) {}
- /*implicit*/ Attributes(Attribute::AttrConst Val) : Bits(Val.v) {}
+ Attributes() : Attrs(0) {}
+ explicit Attributes(uint64_t Val);
+ /*implicit*/ Attributes(Attribute::AttrConst Val);
+ Attributes(const Attributes &A);
class Builder {
friend class Attributes;
uint64_t Bits;
public:
Builder() : Bits(0) {}
- Builder(const Attributes &A) : Bits(A.Bits) {}
-
- void addZExtAttr() {
- Bits |= Attribute::ZExt_i;
- }
- void addSExtAttr() {
- Bits |= Attribute::SExt_i;
- }
- void addNoReturnAttr() {
- Bits |= Attribute::NoReturn_i;
- }
- void addInRegAttr() {
- Bits |= Attribute::InReg_i;
- }
- void addStructRetAttr() {
- Bits |= Attribute::StructRet_i;
- }
- void addNoUnwindAttr() {
- Bits |= Attribute::NoUnwind_i;
- }
- void addNoAliasAttr() {
- Bits |= Attribute::NoAlias_i;
- }
- void addByValAttr() {
- Bits |= Attribute::ByVal_i;
- }
- void addNestAttr() {
- Bits |= Attribute::Nest_i;
- }
- void addReadNoneAttr() {
- Bits |= Attribute::ReadNone_i;
- }
- void addReadOnlyAttr() {
- Bits |= Attribute::ReadOnly_i;
- }
- void addNoInlineAttr() {
- Bits |= Attribute::NoInline_i;
- }
- void addAlwaysInlineAttr() {
- Bits |= Attribute::AlwaysInline_i;
- }
- void addOptimizeForSizeAttr() {
- Bits |= Attribute::OptimizeForSize_i;
- }
- void addStackProtectAttr() {
- Bits |= Attribute::StackProtect_i;
- }
- void addStackProtectReqAttr() {
- Bits |= Attribute::StackProtectReq_i;
- }
- void addNoCaptureAttr() {
- Bits |= Attribute::NoCapture_i;
- }
- void addNoRedZoneAttr() {
- Bits |= Attribute::NoRedZone_i;
- }
- void addNoImplicitFloatAttr() {
- Bits |= Attribute::NoImplicitFloat_i;
- }
- void addNakedAttr() {
- Bits |= Attribute::Naked_i;
- }
- void addInlineHintAttr() {
- Bits |= Attribute::InlineHint_i;
- }
- void addReturnsTwiceAttr() {
- Bits |= Attribute::ReturnsTwice_i;
- }
- void addUWTableAttr() {
- Bits |= Attribute::UWTable_i;
- }
- void addNonLazyBindAttr() {
- Bits |= Attribute::NonLazyBind_i;
- }
- void addAddressSafetyAttr() {
- Bits |= Attribute::AddressSafety_i;
- }
- void addAlignmentAttr(unsigned Align) {
- if (Align == 0) return;
- assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
- assert(Align <= 0x40000000 && "Alignment too large.");
- Bits |= (Log2_32(Align) + 1) << 16;
- }
- void addStackAlignmentAttr(unsigned Align) {
- // Default alignment, allow the target to define how to align it.
- if (Align == 0) return;
-
- assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
- assert(Align <= 0x100 && "Alignment too large.");
- Bits |= (Log2_32(Align) + 1) << 26;
+ Builder(const Attributes &A) : Bits(A.Raw()) {}
+
+ void clear() { Bits = 0; }
+
+ bool hasAttributes() const;
+ bool hasAttributes(const Attributes &A) const;
+ bool hasAlignmentAttr() const;
+
+ uint64_t getAlignment() const;
+
+ Builder &addAttribute(Attributes::AttrVal Val);
+ Builder &removeAttribute(Attributes::AttrVal Val);
+
+ void addAlignmentAttr(unsigned Align);
+ void addStackAlignmentAttr(unsigned Align);
+
+ void removeAttributes(const Attributes &A);
+
+ /// @brief Remove attributes that are used on functions only.
+ void removeFunctionOnlyAttrs() {
+ removeAttribute(Attributes::NoReturn)
+ .removeAttribute(Attributes::NoUnwind)
+ .removeAttribute(Attributes::ReadNone)
+ .removeAttribute(Attributes::ReadOnly)
+ .removeAttribute(Attributes::NoInline)
+ .removeAttribute(Attributes::AlwaysInline)
+ .removeAttribute(Attributes::OptimizeForSize)
+ .removeAttribute(Attributes::StackProtect)
+ .removeAttribute(Attributes::StackProtectReq)
+ .removeAttribute(Attributes::NoRedZone)
+ .removeAttribute(Attributes::NoImplicitFloat)
+ .removeAttribute(Attributes::Naked)
+ .removeAttribute(Attributes::InlineHint)
+ .removeAttribute(Attributes::StackAlignment)
+ .removeAttribute(Attributes::UWTable)
+ .removeAttribute(Attributes::NonLazyBind)
+ .removeAttribute(Attributes::ReturnsTwice)
+ .removeAttribute(Attributes::AddressSafety);
}
};
/// get - Return a uniquified Attributes object. This takes the uniquified
/// value from the Builder and wraps it in the Attributes class.
+ static Attributes get(Builder &B);
static Attributes get(LLVMContext &Context, Builder &B);
- // Attribute query methods.
- // FIXME: StackAlignment & Alignment attributes have no predicate methods.
- bool hasAttributes() const {
- return Bits != 0;
- }
- bool hasAttributes(const Attributes &A) const {
- return Bits & A.Bits;
- }
+ /// @brief Return true if the attribute is present.
+ bool hasAttribute(AttrVal Val) const;
- bool hasZExtAttr() const {
- return Bits & Attribute::ZExt_i;
- }
- bool hasSExtAttr() const {
- return Bits & Attribute::SExt_i;
- }
- bool hasNoReturnAttr() const {
- return Bits & Attribute::NoReturn_i;
- }
- bool hasInRegAttr() const {
- return Bits & Attribute::InReg_i;
- }
- bool hasStructRetAttr() const {
- return Bits & Attribute::StructRet_i;
- }
- bool hasNoUnwindAttr() const {
- return Bits & Attribute::NoUnwind_i;
- }
- bool hasNoAliasAttr() const {
- return Bits & Attribute::NoAlias_i;
- }
- bool hasByValAttr() const {
- return Bits & Attribute::ByVal_i;
- }
- bool hasNestAttr() const {
- return Bits & Attribute::Nest_i;
- }
- bool hasReadNoneAttr() const {
- return Bits & Attribute::ReadNone_i;
- }
- bool hasReadOnlyAttr() const {
- return Bits & Attribute::ReadOnly_i;
- }
- bool hasNoInlineAttr() const {
- return Bits & Attribute::NoInline_i;
- }
- bool hasAlwaysInlineAttr() const {
- return Bits & Attribute::AlwaysInline_i;
- }
- bool hasOptimizeForSizeAttr() const {
- return Bits & Attribute::OptimizeForSize_i;
- }
- bool hasStackProtectAttr() const {
- return Bits & Attribute::StackProtect_i;
- }
- bool hasStackProtectReqAttr() const {
- return Bits & Attribute::StackProtectReq_i;
- }
- bool hasAlignmentAttr() const {
- return Bits & Attribute::Alignment_i;
- }
- bool hasNoCaptureAttr() const {
- return Bits & Attribute::NoCapture_i;
- }
- bool hasNoRedZoneAttr() const {
- return Bits & Attribute::NoRedZone_i;
- }
- bool hasNoImplicitFloatAttr() const {
- return Bits & Attribute::NoImplicitFloat_i;
- }
- bool hasNakedAttr() const {
- return Bits & Attribute::Naked_i;
- }
- bool hasInlineHintAttr() const {
- return Bits & Attribute::InlineHint_i;
- }
- bool hasReturnsTwiceAttr() const {
- return Bits & Attribute::ReturnsTwice_i;
- }
- bool hasStackAlignmentAttr() const {
- return Bits & Attribute::StackAlignment_i;
- }
- bool hasUWTableAttr() const {
- return Bits & Attribute::UWTable_i;
- }
- bool hasNonLazyBindAttr() const {
- return Bits & Attribute::NonLazyBind_i;
- }
- bool hasAddressSafetyAttr() const {
- return Bits & Attribute::AddressSafety_i;
+ /// @brief Return true if attributes exist
+ bool hasAttributes() const {
+ return Attrs.hasAttributes();
}
- /// This returns the alignment field of an attribute as a byte alignment
- /// value.
- unsigned getAlignment() const {
- if (!hasAlignmentAttr())
- return 0;
- return 1U << (((Bits & Attribute::Alignment_i) >> 16) - 1);
- }
+ /// @brief Return true if the attributes are a non-null intersection.
+ bool hasAttributes(const Attributes &A) const;
- /// This returns the stack alignment field of an attribute as a byte alignment
+ /// @brief Returns the alignment field of an attribute as a byte alignment
/// value.
- unsigned getStackAlignment() const {
- if (!hasStackAlignmentAttr())
- return 0;
- return 1U << (((Bits & Attribute::StackAlignment_i) >> 26) - 1);
- }
+ unsigned getAlignment() const;
+
+ /// @brief Returns the stack alignment field of an attribute as a byte
+ /// alignment value.
+ unsigned getStackAlignment() const;
+
+ /// @brief Parameter attributes that do not apply to vararg call arguments.
+ bool hasIncompatibleWithVarArgsAttrs() const {
+ return hasAttribute(Attributes::StructRet);
+ }
+
+ /// @brief Attributes that only apply to function parameters.
+ bool hasParameterOnlyAttrs() const {
+ return hasAttribute(Attributes::ByVal) ||
+ hasAttribute(Attributes::Nest) ||
+ hasAttribute(Attributes::StructRet) ||
+ hasAttribute(Attributes::NoCapture);
+ }
+
+ /// @brief Attributes that may be applied to the function itself. These cannot
+ /// be used on return values or function parameters.
+ bool hasFunctionOnlyAttrs() const {
+ return hasAttribute(Attributes::NoReturn) ||
+ hasAttribute(Attributes::NoUnwind) ||
+ hasAttribute(Attributes::ReadNone) ||
+ hasAttribute(Attributes::ReadOnly) ||
+ hasAttribute(Attributes::NoInline) ||
+ hasAttribute(Attributes::AlwaysInline) ||
+ hasAttribute(Attributes::OptimizeForSize) ||
+ hasAttribute(Attributes::StackProtect) ||
+ hasAttribute(Attributes::StackProtectReq) ||
+ hasAttribute(Attributes::NoRedZone) ||
+ hasAttribute(Attributes::NoImplicitFloat) ||
+ hasAttribute(Attributes::Naked) ||
+ hasAttribute(Attributes::InlineHint) ||
+ hasAttribute(Attributes::StackAlignment) ||
+ hasAttribute(Attributes::UWTable) ||
+ hasAttribute(Attributes::NonLazyBind) ||
+ hasAttribute(Attributes::ReturnsTwice) ||
+ hasAttribute(Attributes::AddressSafety);
+ }
+
+ bool isEmptyOrSingleton() const;
// This is a "safe bool() operator".
- operator const void *() const { return Bits ? this : 0; }
- bool isEmptyOrSingleton() const { return (Bits & (Bits - 1)) == 0; }
- bool operator == (const Attributes &Attrs) const {
- return Bits == Attrs.Bits;
- }
- bool operator != (const Attributes &Attrs) const {
- return Bits != Attrs.Bits;
- }
- Attributes operator | (const Attributes &Attrs) const {
- return Attributes(Bits | Attrs.Bits);
- }
- Attributes operator & (const Attributes &Attrs) const {
- return Attributes(Bits & Attrs.Bits);
+ operator const void *() const { return Attrs.Bits ? this : 0; }
+ bool operator == (const Attributes &A) const {
+ return Attrs.Bits == A.Attrs.Bits;
}
- Attributes operator ^ (const Attributes &Attrs) const {
- return Attributes(Bits ^ Attrs.Bits);
+ bool operator != (const Attributes &A) const {
+ return Attrs.Bits != A.Attrs.Bits;
}
- Attributes &operator |= (const Attributes &Attrs) {
- Bits |= Attrs.Bits;
- return *this;
- }
- Attributes &operator &= (const Attributes &Attrs) {
- Bits &= Attrs.Bits;
- return *this;
- }
- Attributes operator ~ () const { return Attributes(~Bits); }
- uint64_t Raw() const { return Bits; }
- /// This turns an int alignment (a power of 2, normally) into the form used
- /// internally in Attributes.
+ Attributes operator | (const Attributes &A) const;
+ Attributes operator & (const Attributes &A) const;
+ Attributes operator ^ (const Attributes &A) const;
+ Attributes &operator |= (const Attributes &A);
+ Attributes &operator &= (const Attributes &A);
+ Attributes operator ~ () const;
+
+ uint64_t Raw() const;
+
+ /// constructAlignmentFromInt - This turns an int alignment (a power of 2,
+ /// normally) into the form used internally in Attributes.
static Attributes constructAlignmentFromInt(unsigned i) {
// Default alignment, allow the target to define how to align it.
if (i == 0)
- return Attribute::None;
+ return Attributes();
assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
assert(i <= 0x40000000 && "Alignment too large.");
return Attributes((Log2_32(i)+1) << 16);
}
- /// This turns an int stack alignment (which must be a power of 2) into the
- /// form used internally in Attributes.
+ /// constructStackAlignmentFromInt - This turns an int stack alignment (which
+ /// must be a power of 2) into the form used internally in Attributes.
static Attributes constructStackAlignmentFromInt(unsigned i) {
// Default alignment, allow the target to define how to align it.
if (i == 0)
- return Attribute::None;
+ return Attributes();
assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
assert(i <= 0x100 && "Alignment too large.");
@@ -415,9 +317,9 @@ public:
/// @brief Which attributes cannot be applied to a type.
static Attributes typeIncompatible(Type *Ty);
- /// This returns an integer containing an encoding of all the LLVM attributes
- /// found in the given attribute bitset. Any change to this encoding is a
- /// breaking change to bitcode compatibility.
+ /// encodeLLVMAttributesForBitcode - This returns an integer containing an
+ /// encoding of all the LLVM attributes found in the given attribute bitset.
+ /// Any change to this encoding is a breaking change to bitcode compatibility.
static uint64_t encodeLLVMAttributesForBitcode(Attributes Attrs) {
// FIXME: It doesn't make sense to store the alignment information as an
// expanded out value, we should store it as a log2 value. However, we
@@ -430,15 +332,15 @@ public:
// 5-bit log2 encoded value. Shift the bits above the alignment up by 11
// bits.
uint64_t EncodedAttrs = Attrs.Raw() & 0xffff;
- if (Attrs.hasAlignmentAttr())
- EncodedAttrs |= (1ULL << 16) <<
- (((Attrs.Bits & Attribute::Alignment_i) - 1) >> 16);
+ if (Attrs.hasAttribute(Attributes::Alignment))
+ EncodedAttrs |= Attrs.getAlignment() << 16;
EncodedAttrs |= (Attrs.Raw() & (0xfffULL << 21)) << 11;
return EncodedAttrs;
}
- /// This returns an attribute bitset containing the LLVM attributes that have
- /// been decoded from the given integer. This function must stay in sync with
+ /// decodeLLVMAttributesForBitcode - This returns an attribute bitset
+ /// containing the LLVM attributes that have been decoded from the given
+ /// integer. This function must stay in sync with
/// 'encodeLLVMAttributesForBitcode'.
static Attributes decodeLLVMAttributesForBitcode(uint64_t EncodedAttrs) {
// The alignment is stored as a 16-bit raw value from bits 31--16. We shift
@@ -454,15 +356,19 @@ public:
return Attrs;
}
- /// The set of Attributes set in Attributes is converted to a string of
- /// equivalent mnemonics. This is, presumably, for writing out the mnemonics
- /// for the assembly writer.
+ /// getAsString - The set of Attributes set in Attributes is converted to a
+ /// string of equivalent mnemonics. This is, presumably, for writing out the
+ /// mnemonics for the assembly writer.
/// @brief Convert attribute bits to text
std::string getAsString() const;
};
-/// This is just a pair of values to associate a set of attributes
-/// with an index.
+//===----------------------------------------------------------------------===//
+// AttributeWithIndex
+//===----------------------------------------------------------------------===//
+
+/// AttributeWithIndex - This is just a pair of values to associate a set of
+/// attributes with an index.
struct AttributeWithIndex {
Attributes Attrs; ///< The attributes that are set, or'd together.
unsigned Index; ///< Index of the parameter for which the attributes apply.
@@ -518,7 +424,6 @@ public:
/// getParamAttributes - The attributes for the specified index are
/// returned.
Attributes getParamAttributes(unsigned Idx) const {
- assert (Idx && Idx != ~0U && "Invalid parameter index!");
return getAttributes(Idx);
}
@@ -549,6 +454,9 @@ public:
/// least one parameter or for the return value.
bool hasAttrSomewhere(Attributes Attr) const;
+ unsigned getNumAttrs() const;
+ Attributes &getAttributesAtIndex(unsigned i) const;
+
/// operator==/!= - Provide equality predicates.
bool operator==(const AttrListPtr &RHS) const
{ return AttrList == RHS.AttrList; }
@@ -592,7 +500,6 @@ private:
/// getAttributes - The attributes for the specified index are
/// returned. Attributes for the result are denoted with Idx = 0.
Attributes getAttributes(unsigned Idx) const;
-
};
} // End llvm namespace
diff --git a/lib/VMCore/AttributesImpl.h b/include/llvm/AttributesImpl.h
index 90890a14c3..eea11a7011 100644
--- a/lib/VMCore/AttributesImpl.h
+++ b/include/llvm/AttributesImpl.h
@@ -19,14 +19,27 @@
namespace llvm {
+class Attributes;
+
class AttributesImpl : public FoldingSetNode {
+ friend class Attributes;
uint64_t Bits; // FIXME: We will be expanding this.
- void operator=(const AttributesImpl &) LLVM_DELETED_FUNCTION;
- AttributesImpl(const AttributesImpl &) LLVM_DELETED_FUNCTION;
public:
AttributesImpl(uint64_t bits) : Bits(bits) {}
+ bool hasAttribute(uint64_t A) const;
+
+ bool hasAttributes() const;
+ bool hasAttributes(const Attributes &A) const;
+
+ uint64_t getAlignment() const;
+ uint64_t getStackAlignment() const;
+
+ bool isEmptyOrSingleton() const;
+
+ static uint64_t getAttrMask(uint64_t Val);
+
void Profile(FoldingSetNodeID &ID) const {
Profile(ID, Bits);
}
diff --git a/include/llvm/CallingConv.h b/include/llvm/CallingConv.h
index 4c5ee62670..86e4eebb82 100644
--- a/include/llvm/CallingConv.h
+++ b/include/llvm/CallingConv.h
@@ -94,7 +94,25 @@ namespace CallingConv {
/// MBLAZE_INTR - Calling convention used for MBlaze interrupt support
/// routines (i.e. GCC's save_volatiles attribute).
- MBLAZE_SVOL = 74
+ MBLAZE_SVOL = 74,
+
+ /// SPIR_FUNC - Calling convention for SPIR non-kernel device functions.
+ /// No lowering or expansion of arguments.
+ /// Structures are passed as a pointer to a struct with the byval attribute.
+ /// Functions can only call SPIR_FUNC and SPIR_KERNEL functions.
+ /// Functions can only have zero or one return values.
+ /// Variable arguments are not allowed, except for printf.
+ /// How arguments/return values are lowered are not specified.
+ /// Functions are only visible to the devices.
+ SPIR_FUNC = 75,
+
+ /// SPIR_KERNEL - Calling convention for SPIR kernel functions.
+ /// Inherits the restrictions of SPIR_FUNC, except
+ /// Cannot have non-void return values.
+ /// Cannot have variable arguments.
+ /// Can also be called by the host.
+ /// Is externally visible.
+ SPIR_KERNEL = 76
};
} // End CallingConv namespace
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index b8d435ee13..02c5f422ce 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -48,7 +48,7 @@ namespace llvm {
class DwarfException;
class Mangler;
class TargetLoweringObjectFile;
- class TargetData;
+ class DataLayout;
class TargetMachine;
/// AsmPrinter - This class is intended to be used as a driving class for all
@@ -137,8 +137,8 @@ namespace llvm {
/// getObjFileLowering - Return information about object file lowering.
const TargetLoweringObjectFile &getObjFileLowering() const;
- /// getTargetData - Return information about data layout.
- const TargetData &getTargetData() const;
+ /// getDataLayout - Return information about data layout.
+ const DataLayout &getDataLayout() const;
/// getCurrentSection() - Return the current section we are emitting to.
const MCSection *getCurrentSection() const;
diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h
index 59e7520d24..c1bc3aba5e 100644
--- a/include/llvm/CodeGen/CallingConvLower.h
+++ b/include/llvm/CodeGen/CallingConvLower.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Target/TargetCallingConv.h"
#include "llvm/CallingConv.h"
@@ -289,6 +290,7 @@ public:
StackOffset = ((StackOffset + Align-1) & ~(Align-1));
unsigned Result = StackOffset;
StackOffset += Size;
+ MF.getFrameInfo()->ensureMaxAlignment(Align);
return Result;
}
diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h
index 7cb96952aa..7c24e36092 100644
--- a/include/llvm/CodeGen/FastISel.h
+++ b/include/llvm/CodeGen/FastISel.h
@@ -32,7 +32,7 @@ class MachineFunction;
class MachineInstr;
class MachineFrameInfo;
class MachineRegisterInfo;
-class TargetData;
+class DataLayout;
class TargetInstrInfo;
class TargetLibraryInfo;
class TargetLowering;
@@ -54,7 +54,7 @@ protected:
MachineConstantPool &MCP;
DebugLoc DL;
const TargetMachine &TM;
- const TargetData &TD;
+ const DataLayout &TD;
const TargetInstrInfo &TII;
const TargetLowering &TLI;
const TargetRegisterInfo &TRI;
diff --git a/include/llvm/CodeGen/IntrinsicLowering.h b/include/llvm/CodeGen/IntrinsicLowering.h
index c5ffc7ec0e..dcb013e1f9 100644
--- a/include/llvm/CodeGen/IntrinsicLowering.h
+++ b/include/llvm/CodeGen/IntrinsicLowering.h
@@ -22,16 +22,16 @@
namespace llvm {
class CallInst;
class Module;
- class TargetData;
+ class DataLayout;
class IntrinsicLowering {
- const TargetData& TD;
+ const DataLayout& TD;
static StringSet<> FuncNames; // @LOCALMOD
bool Warned;
public:
- explicit IntrinsicLowering(const TargetData &td) :
+ explicit IntrinsicLowering(const DataLayout &td) :
TD(td), Warned(false) {}
/// @LOCALMOD-BEGIN
diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h
index b0a70a872e..827a9f81e8 100644
--- a/include/llvm/CodeGen/MachineConstantPool.h
+++ b/include/llvm/CodeGen/MachineConstantPool.h
@@ -25,7 +25,7 @@ namespace llvm {
class Constant;
class FoldingSetNodeID;
-class TargetData;
+class DataLayout;
class TargetMachine;
class Type;
class MachineConstantPool;
@@ -143,14 +143,14 @@ public:
/// address of the function constant pool values.
/// @brief The machine constant pool.
class MachineConstantPool {
- const TargetData *TD; ///< The machine's TargetData.
+ const DataLayout *TD; ///< The machine's DataLayout.
unsigned PoolAlignment; ///< The alignment for the pool.
std::vector<MachineConstantPoolEntry> Constants; ///< The pool of constants.
/// MachineConstantPoolValues that use an existing MachineConstantPoolEntry.
DenseSet<MachineConstantPoolValue*> MachineCPVsSharingEntries;
public:
/// @brief The only constructor.
- explicit MachineConstantPool(const TargetData *td)
+ explicit MachineConstantPool(const DataLayout *td)
: TD(td), PoolAlignment(1) {}
~MachineConstantPool();
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index 3c07cebfcc..7188b1abbd 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -21,7 +21,7 @@
namespace llvm {
class raw_ostream;
-class TargetData;
+class DataLayout;
class TargetRegisterClass;
class Type;
class MachineFunction;
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index 32c79510d8..eab74bd301 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -98,25 +98,10 @@ private:
/// MCID NULL and no operands.
MachineInstr();
- // The next two constructors have DebugLoc and non-DebugLoc versions;
- // over time, the non-DebugLoc versions should be phased out and eventually
- // removed.
-
- /// MachineInstr ctor - This constructor creates a MachineInstr and adds the
- /// implicit operands. It reserves space for the number of operands specified
- /// by the MCInstrDesc. The version with a DebugLoc should be preferred.
- explicit MachineInstr(const MCInstrDesc &MCID, bool NoImp = false);
-
- /// MachineInstr ctor - Work exactly the same as the ctor above, except that
- /// the MachineInstr is created and added to the end of the specified basic
- /// block. The version with a DebugLoc should be preferred.
- MachineInstr(MachineBasicBlock *MBB, const MCInstrDesc &MCID);
-
/// MachineInstr ctor - This constructor create a MachineInstr and add the
/// implicit operands. It reserves space for number of operands specified by
/// MCInstrDesc. An explicit DebugLoc is supplied.
- explicit MachineInstr(const MCInstrDesc &MCID, const DebugLoc dl,
- bool NoImp = false);
+ MachineInstr(const MCInstrDesc &MCID, const DebugLoc dl, bool NoImp = false);
/// MachineInstr ctor - Work exactly the same as the ctor above, except that
/// the MachineInstr is created and added to the end of the specified basic
diff --git a/include/llvm/CodeGen/MachineJumpTableInfo.h b/include/llvm/CodeGen/MachineJumpTableInfo.h
index f7c4e8642d..928145d279 100644
--- a/include/llvm/CodeGen/MachineJumpTableInfo.h
+++ b/include/llvm/CodeGen/MachineJumpTableInfo.h
@@ -26,7 +26,7 @@
namespace llvm {
class MachineBasicBlock;
-class TargetData;
+class DataLayout;
class raw_ostream;
/// MachineJumpTableEntry - One jump table in the jump table info.
@@ -84,9 +84,9 @@ public:
JTEntryKind getEntryKind() const { return EntryKind; }
/// getEntrySize - Return the size of each entry in the jump table.
- unsigned getEntrySize(const TargetData &TD) const;
+ unsigned getEntrySize(const DataLayout &TD) const;
/// getEntryAlignment - Return the alignment of each entry in the jump table.
- unsigned getEntryAlignment(const TargetData &TD) const;
+ unsigned getEntryAlignment(const DataLayout &TD) const;
/// createJumpTableIndex - Create a new jump table.
///
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h
index 2567a65733..744e2ee923 100644
--- a/include/llvm/CodeGen/ScheduleDAG.h
+++ b/include/llvm/CodeGen/ScheduleDAG.h
@@ -575,11 +575,6 @@ namespace llvm {
///
virtual void computeLatency(SUnit *SU) = 0;
- /// ForceUnitLatencies - Return true if all scheduling edges should be given
- /// a latency value of one. The default is to return false; schedulers may
- /// override this as needed.
- virtual bool forceUnitLatencies() const { return false; }
-
private:
// Return the MCInstrDesc of this SDNode or NULL.
const MCInstrDesc *getNodeDesc(const SDNode *Node) const;
diff --git a/include/llvm/CodeGen/TargetSchedule.h b/include/llvm/CodeGen/TargetSchedule.h
index d2a26afe99..541ee66c0c 100644
--- a/include/llvm/CodeGen/TargetSchedule.h
+++ b/include/llvm/CodeGen/TargetSchedule.h
@@ -63,6 +63,7 @@ public:
bool FindMin) const;
unsigned getProcessorID() const { return SchedModel.getProcessorID(); }
+ unsigned getIssueWidth() const { return SchedModel.IssueWidth; }
private:
/// getDefLatency is a helper for computeOperandLatency. Return the
diff --git a/include/llvm/DIBuilder.h b/include/llvm/DIBuilder.h
index 80880094d2..2f07800680 100644
--- a/include/llvm/DIBuilder.h
+++ b/include/llvm/DIBuilder.h
@@ -331,12 +331,10 @@ namespace llvm {
/// @param SizeInBits Member size.
/// @param AlignInBits Member alignment.
/// @param Elements Enumeration elements.
- /// @param Flags Flags (e.g. forward decl)
DIType createEnumerationType(DIDescriptor Scope, StringRef Name,
DIFile File, unsigned LineNumber,
uint64_t SizeInBits, uint64_t AlignInBits,
- DIArray Elements, DIType ClassType,
- unsigned Flags);
+ DIArray Elements, DIType ClassType);
/// createSubroutineType - Create subroutine type.
/// @param File File in which this subroutine is defined.
@@ -357,7 +355,8 @@ namespace llvm {
/// createForwardDecl - Create a temporary forward-declared type.
DIType createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Scope,
- DIFile F, unsigned Line, unsigned RuntimeLang = 0);
+ DIFile F, unsigned Line, unsigned RuntimeLang = 0,
+ uint64_t SizeInBits = 0, uint64_t AlignInBits = 0);
/// retainType - Retain DIType in a module even if it is not referenced
/// through debug info anchors.
diff --git a/include/llvm/Target/TargetData.h b/include/llvm/DataLayout.h
index c97af7db68..a24737e842 100644
--- a/include/llvm/Target/TargetData.h
+++ b/include/llvm/DataLayout.h
@@ -1,4 +1,4 @@
-//===-- llvm/Target/TargetData.h - Data size & alignment info ---*- C++ -*-===//
+//===--------- llvm/DataLayout.h - Data size & alignment info ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines target properties related to datatype size/offset/alignment
+// This file defines layout properties related to datatype size/offset/alignment
// information. It uses lazy annotations to cache information about how
// structure types are laid out and used.
//
@@ -17,11 +17,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TARGET_TARGETDATA_H
-#define LLVM_TARGET_TARGETDATA_H
+#ifndef LLVM_DATALAYOUT_H
+#define LLVM_DATALAYOUT_H
#include "llvm/Pass.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -36,7 +37,7 @@ class LLVMContext;
template<typename T>
class ArrayRef;
-/// Enum used to categorize the alignment types stored by TargetAlignElem
+/// Enum used to categorize the alignment types stored by LayoutAlignElem
enum AlignTypeEnum {
INTEGER_ALIGN = 'i', ///< Integer type alignment
VECTOR_ALIGN = 'v', ///< Vector type alignment
@@ -45,38 +46,55 @@ enum AlignTypeEnum {
STACK_ALIGN = 's' ///< Stack objects alignment
};
-/// Target alignment element.
+/// Layout alignment element.
///
-/// Stores the alignment data associated with a given alignment type (pointer,
-/// integer, vector, float) and type bit width.
+/// Stores the alignment data associated with a given alignment type (integer,
+/// vector, float) and type bit width.
///
/// @note The unusual order of elements in the structure attempts to reduce
/// padding and make the structure slightly more cache friendly.
-struct TargetAlignElem {
- uint32_t AlignType : 8; ///< Alignment type (AlignTypeEnum)
- uint32_t TypeBitWidth : 24; ///< Type bit width
- uint32_t ABIAlign : 16; ///< ABI alignment for this type/bitw
- uint32_t PrefAlign : 16; ///< Pref. alignment for this type/bitw
+struct LayoutAlignElem {
+ unsigned AlignType : 8; ///< Alignment type (AlignTypeEnum)
+ unsigned TypeBitWidth : 24; ///< Type bit width
+ unsigned ABIAlign : 16; ///< ABI alignment for this type/bitw
+ unsigned PrefAlign : 16; ///< Pref. alignment for this type/bitw
/// Initializer
- static TargetAlignElem get(AlignTypeEnum align_type, unsigned abi_align,
+ static LayoutAlignElem get(AlignTypeEnum align_type, unsigned abi_align,
unsigned pref_align, uint32_t bit_width);
/// Equality predicate
- bool operator==(const TargetAlignElem &rhs) const;
+ bool operator==(const LayoutAlignElem &rhs) const;
};
-/// TargetData - This class holds a parsed version of the target data layout
+/// Layout pointer alignment element.
+///
+/// Stores the alignment data associated with a given pointer and address space.
+///
+/// @note The unusual order of elements in the structure attempts to reduce
+/// padding and make the structure slightly more cache friendly.
+struct PointerAlignElem {
+ unsigned ABIAlign; ///< ABI alignment for this type/bitw
+ unsigned PrefAlign; ///< Pref. alignment for this type/bitw
+ uint32_t TypeBitWidth; ///< Type bit width
+ uint32_t AddressSpace; ///< Address space for the pointer type
+
+ /// Initializer
+ static PointerAlignElem get(uint32_t addr_space, unsigned abi_align,
+ unsigned pref_align, uint32_t bit_width);
+ /// Equality predicate
+ bool operator==(const PointerAlignElem &rhs) const;
+};
+
+
+/// DataLayout - This class holds a parsed version of the target data layout
/// string in a module and provides methods for querying it. The target data
/// layout string is specified *by the target* - a frontend generating LLVM IR
/// is required to generate the right target data for the target being codegen'd
/// to. If some measure of portability is desired, an empty string may be
/// specified in the module.
-class TargetData : public ImmutablePass {
+class DataLayout : public ImmutablePass {
private:
bool LittleEndian; ///< Defaults to false
- unsigned PointerMemSize; ///< Pointer size in bytes
- unsigned PointerABIAlign; ///< Pointer ABI alignment
- unsigned PointerPrefAlign; ///< Pointer preferred alignment
unsigned StackNaturalAlign; ///< Stack natural alignment
SmallVector<unsigned char, 8> LegalIntWidths; ///< Legal Integers.
@@ -85,13 +103,18 @@ private:
///
/// @sa init().
/// @note Could support multiple size pointer alignments, e.g., 32-bit
- /// pointers vs. 64-bit pointers by extending TargetAlignment, but for now,
+ /// pointers vs. 64-bit pointers by extending LayoutAlignment, but for now,
/// we don't.
- SmallVector<TargetAlignElem, 16> Alignments;
+ SmallVector<LayoutAlignElem, 16> Alignments;
+ DenseMap<unsigned, PointerAlignElem> Pointers;
/// InvalidAlignmentElem - This member is a signal that a requested alignment
/// type and bit width were not found in the SmallVector.
- static const TargetAlignElem InvalidAlignmentElem;
+ static const LayoutAlignElem InvalidAlignmentElem;
+
+ /// InvalidPointerElem - This member is a signal that a requested pointer
+ /// type and bit width were not found in the DenseSet.
+ static const PointerAlignElem InvalidPointerElem;
// The StructType -> StructLayout map.
mutable void *LayoutMap;
@@ -101,18 +124,31 @@ private:
unsigned pref_align, uint32_t bit_width);
unsigned getAlignmentInfo(AlignTypeEnum align_type, uint32_t bit_width,
bool ABIAlign, Type *Ty) const;
+
+ //! Set/initialize pointer alignments
+ void setPointerAlignment(uint32_t addr_space, unsigned abi_align,
+ unsigned pref_align, uint32_t bit_width);
+
//! Internal helper method that returns requested alignment for type.
unsigned getAlignment(Type *Ty, bool abi_or_pref) const;
/// Valid alignment predicate.
///
- /// Predicate that tests a TargetAlignElem reference returned by get() against
+ /// Predicate that tests a LayoutAlignElem reference returned by get() against
/// InvalidAlignmentElem.
- bool validAlignment(const TargetAlignElem &align) const {
+ bool validAlignment(const LayoutAlignElem &align) const {
return &align != &InvalidAlignmentElem;
}
- /// Initialise a TargetData object with default values, ensure that the
+ /// Valid pointer predicate.
+ ///
+ /// Predicate that tests a PointerAlignElem reference returned by get() against
+ /// InvalidPointerElem.
+ bool validPointer(const PointerAlignElem &align) const {
+ return &align != &InvalidPointerElem;
+ }
+
+ /// Initialise a DataLayout object with default values, ensure that the
/// target data pass is registered.
void init();
@@ -121,43 +157,42 @@ public:
///
/// @note This has to exist, because this is a pass, but it should never be
/// used.
- TargetData();
+ DataLayout();
- /// Constructs a TargetData from a specification string. See init().
- explicit TargetData(StringRef TargetDescription)
+ /// Constructs a DataLayout from a specification string. See init().
+ explicit DataLayout(StringRef LayoutDescription)
: ImmutablePass(ID) {
- std::string errMsg = parseSpecifier(TargetDescription, this);
+ std::string errMsg = parseSpecifier(LayoutDescription, this);
assert(errMsg == "" && "Invalid target data layout string.");
(void)errMsg;
}
/// Parses a target data specification string. Returns an error message
/// if the string is malformed, or the empty string on success. Optionally
- /// initialises a TargetData object if passed a non-null pointer.
- static std::string parseSpecifier(StringRef TargetDescription, TargetData* td = 0);
+ /// initialises a DataLayout object if passed a non-null pointer.
+ static std::string parseSpecifier(StringRef LayoutDescription,
+ DataLayout* td = 0);
/// Initialize target data from properties stored in the module.
- explicit TargetData(const Module *M);
+ explicit DataLayout(const Module *M);
- TargetData(const TargetData &TD) :
+ DataLayout(const DataLayout &TD) :
ImmutablePass(ID),
LittleEndian(TD.isLittleEndian()),
- PointerMemSize(TD.PointerMemSize),
- PointerABIAlign(TD.PointerABIAlign),
- PointerPrefAlign(TD.PointerPrefAlign),
LegalIntWidths(TD.LegalIntWidths),
Alignments(TD.Alignments),
+ Pointers(TD.Pointers),
LayoutMap(0)
{ }
- ~TargetData(); // Not virtual, do not subclass this class
+ ~DataLayout(); // Not virtual, do not subclass this class
- /// Target endianness...
+ /// Layout endianness...
bool isLittleEndian() const { return LittleEndian; }
bool isBigEndian() const { return !LittleEndian; }
/// getStringRepresentation - Return the string representation of the
- /// TargetData. This representation is in the same format accepted by the
+ /// DataLayout. This representation is in the same format accepted by the
/// string constructor above.
std::string getStringRepresentation() const;
@@ -195,15 +230,46 @@ public:
return false;
}
- /// Target pointer alignment
- unsigned getPointerABIAlignment() const { return PointerABIAlign; }
+ /// Layout pointer alignment
+ /// FIXME: The defaults need to be removed once all of
+ /// the backends/clients are updated.
+ unsigned getPointerABIAlignment(unsigned AS = 0) const {
+ DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS);
+ if (val == Pointers.end()) {
+ val = Pointers.find(0);
+ }
+ return val->second.ABIAlign;
+ }
/// Return target's alignment for stack-based pointers
- unsigned getPointerPrefAlignment() const { return PointerPrefAlign; }
- /// Target pointer size
- unsigned getPointerSize() const { return PointerMemSize; }
- /// Target pointer size, in bits
- unsigned getPointerSizeInBits() const { return 8*PointerMemSize; }
-
+ /// FIXME: The defaults need to be removed once all of
+ /// the backends/clients are updated.
+ unsigned getPointerPrefAlignment(unsigned AS = 0) const {
+ DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS);
+ if (val == Pointers.end()) {
+ val = Pointers.find(0);
+ }
+ return val->second.PrefAlign;
+ }
+ /// Layout pointer size
+ /// FIXME: The defaults need to be removed once all of
+ /// the backends/clients are updated.
+ unsigned getPointerSize(unsigned AS = 0) const {
+ DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS);
+ if (val == Pointers.end()) {
+ val = Pointers.find(0);
+ }
+ return val->second.TypeBitWidth;
+ }
+ /// Layout pointer size, in bits
+ /// FIXME: The defaults need to be removed once all of
+ /// the backends/clients are updated.
+ unsigned getPointerSizeInBits(unsigned AS = 0) const {
+ DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS);
+ if (val == Pointers.end()) {
+ val = Pointers.find(0);
+ }
+ return 8*val->second.TypeBitWidth;
+ }
/// Size examples:
///
/// Type SizeInBits StoreSizeInBits AllocSizeInBits[*]
@@ -281,8 +347,9 @@ public:
/// getIntPtrType - Return an unsigned integer type that is the same size or
/// greater to the host pointer size.
- ///
- IntegerType *getIntPtrType(LLVMContext &C) const;
+ /// FIXME: Need to remove the default argument when the rest of the LLVM code
+ /// base has been updated.
+ IntegerType *getIntPtrType(LLVMContext &C, unsigned AddressSpace = 0) const;
/// getIndexedOffset - return the offset from the beginning of the type for
/// the specified indices. This is used to implement getelementptr.
@@ -318,7 +385,7 @@ public:
};
/// StructLayout - used to lazily calculate structure layout information for a
-/// target machine, based on the TargetData structure.
+/// target machine, based on the DataLayout structure.
///
class StructLayout {
uint64_t StructSize;
@@ -354,8 +421,8 @@ public:
}
private:
- friend class TargetData; // Only TargetData can create this class
- StructLayout(StructType *ST, const TargetData &TD);
+ friend class DataLayout; // Only DataLayout can create this class
+ StructLayout(StructType *ST, const DataLayout &TD);
};
} // End llvm namespace
diff --git a/include/llvm/DebugInfo.h b/include/llvm/DebugInfo.h
index 4c1d045fa0..dae03ad100 100644
--- a/include/llvm/DebugInfo.h
+++ b/include/llvm/DebugInfo.h
@@ -81,6 +81,7 @@ namespace llvm {
GlobalVariable *getGlobalVariableField(unsigned Elt) const;
Constant *getConstantField(unsigned Elt) const;
Function *getFunctionField(unsigned Elt) const;
+ void replaceFunctionField(unsigned Elt, Function *F);
public:
explicit DIDescriptor() : DbgNode(0) {}
@@ -562,6 +563,7 @@ namespace llvm {
bool describes(const Function *F);
Function *getFunction() const { return getFunctionField(16); }
+ void replaceFunction(Function *F) { replaceFunctionField(16, F); }
DIArray getTemplateParams() const { return getFieldAs<DIArray>(17); }
DISubprogram getFunctionDeclaration() const {
return getFieldAs<DISubprogram>(18);
diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h
index 9a723084a6..da1e62dc04 100644
--- a/include/llvm/DerivedTypes.h
+++ b/include/llvm/DerivedTypes.h
@@ -19,8 +19,8 @@
#define LLVM_DERIVED_TYPES_H
#include "llvm/Type.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Compiler.h"
namespace llvm {
@@ -184,7 +184,7 @@ public:
/// Independent of what kind of struct you have, the body of a struct type are
/// laid out in memory consequtively with the elements directly one after the
/// other (if the struct is packed) or (if not packed) with padding between the
-/// elements as defined by TargetData (which is required to match what the code
+/// elements as defined by DataLayout (which is required to match what the code
/// generator for a target expects).
///
class StructType : public CompositeType {
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
index 3c6d3b8dbf..04756ca601 100644
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -42,7 +42,7 @@ class JITMemoryManager;
class MachineCodeInfo;
class Module;
class MutexGuard;
-class TargetData;
+class DataLayout;
class Triple;
class Type;
@@ -104,7 +104,7 @@ class ExecutionEngine {
ExecutionEngineState EEState;
/// The target data for the platform for which execution is being performed.
- const TargetData *TD;
+ const DataLayout *TD;
/// Whether lazy JIT compilation is enabled.
bool CompilingLazily;
@@ -123,7 +123,7 @@ protected:
/// optimize for the case where there is only one module.
SmallVector<Module*, 1> Modules;
- void setTargetData(const TargetData *td) { TD = td; }
+ void setDataLayout(const DataLayout *td) { TD = td; }
/// getMemoryforGV - Allocate memory for a global variable.
virtual char *getMemoryForGV(const GlobalVariable *GV);
@@ -213,7 +213,7 @@ public:
//===--------------------------------------------------------------------===//
- const TargetData *getTargetData() const { return TD; }
+ const DataLayout *getDataLayout() const { return TD; }
/// removeModule - Remove a Module from the list of modules. Returns true if
/// M is found.
diff --git a/include/llvm/ExecutionEngine/ObjectBuffer.h b/include/llvm/ExecutionEngine/ObjectBuffer.h
new file mode 100644
index 0000000000..a0a77b8ba8
--- /dev/null
+++ b/include/llvm/ExecutionEngine/ObjectBuffer.h
@@ -0,0 +1,80 @@
+//===---- ObjectBuffer.h - Utility class to wrap object image memory -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a wrapper class to hold the memory into which an
+// object will be generated.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_OBJECTBUFFER_H
+#define LLVM_EXECUTIONENGINE_OBJECTBUFFER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+namespace llvm {
+
+/// ObjectBuffer - This class acts as a container for the memory buffer used during
+/// generation and loading of executable objects using MCJIT and RuntimeDyld. The
+/// underlying memory for the object will be owned by the ObjectBuffer instance
+/// throughout its lifetime. The getMemBuffer() method provides a way to create a
+/// MemoryBuffer wrapper object instance to be owned by other classes (such as
+/// ObjectFile) as needed, but the MemoryBuffer instance returned does not own the
+/// actual memory it points to.
+class ObjectBuffer {
+public:
+ ObjectBuffer() {}
+ ObjectBuffer(MemoryBuffer* Buf) : Buffer(Buf) {}
+ virtual ~ObjectBuffer() {}
+
+ /// getMemBuffer - Like MemoryBuffer::getMemBuffer() this function
+ /// returns a pointer to an object that is owned by the caller. However,
+ /// the caller does not take ownership of the underlying memory.
+ MemoryBuffer *getMemBuffer() const {
+ return MemoryBuffer::getMemBuffer(Buffer->getBuffer(), "", false);
+ }
+
+ const char *getBufferStart() const { return Buffer->getBufferStart(); }
+ size_t getBufferSize() const { return Buffer->getBufferSize(); }
+
+protected:
+ // The memory contained in an ObjectBuffer
+ OwningPtr<MemoryBuffer> Buffer;
+};
+
+/// ObjectBufferStream - This class encapsulates the SmallVector and
+/// raw_svector_ostream needed to generate an object using MC code emission
+/// while providing a common ObjectBuffer interface for access to the
+/// memory once the object has been generated.
+class ObjectBufferStream : public ObjectBuffer {
+public:
+ ObjectBufferStream() : OS(SV) {}
+ virtual ~ObjectBufferStream() {}
+
+ raw_ostream &getOStream() { return OS; }
+ void flush()
+ {
+ OS.flush();
+
+ // Make the data accessible via the ObjectBuffer::Buffer
+ Buffer.reset(MemoryBuffer::getMemBuffer(StringRef(SV.data(), SV.size()),
+ "",
+ false));
+ }
+
+protected:
+ SmallVector<char, 4096> SV; // Working buffer into which we JIT.
+ raw_svector_ostream OS; // streaming wrapper
+};
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/ExecutionEngine/ObjectImage.h b/include/llvm/ExecutionEngine/ObjectImage.h
new file mode 100644
index 0000000000..82549add62
--- /dev/null
+++ b/include/llvm/ExecutionEngine/ObjectImage.h
@@ -0,0 +1,61 @@
+//===---- ObjectImage.h - Format independent executuable object image -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a file format independent ObjectImage class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_OBJECTIMAGE_H
+#define LLVM_EXECUTIONENGINE_OBJECTIMAGE_H
+
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
+
+namespace llvm {
+
+
+/// ObjectImage - A container class that represents an ObjectFile that has been
+/// or is in the process of being loaded into memory for execution.
+class ObjectImage {
+ ObjectImage() LLVM_DELETED_FUNCTION;
+ ObjectImage(const ObjectImage &other) LLVM_DELETED_FUNCTION;
+
+protected:
+ OwningPtr<ObjectBuffer> Buffer;
+
+public:
+ ObjectImage(ObjectBuffer *Input) : Buffer(Input) {}
+ virtual ~ObjectImage() {}
+
+ virtual object::symbol_iterator begin_symbols() const = 0;
+ virtual object::symbol_iterator end_symbols() const = 0;
+
+ virtual object::section_iterator begin_sections() const = 0;
+ virtual object::section_iterator end_sections() const = 0;
+
+ virtual /* Triple::ArchType */ unsigned getArch() const = 0;
+
+ // Subclasses can override these methods to update the image with loaded
+ // addresses for sections and common symbols
+ virtual void updateSectionAddress(const object::SectionRef &Sec,
+ uint64_t Addr) = 0;
+ virtual void updateSymbolAddress(const object::SymbolRef &Sym,
+ uint64_t Addr) = 0;
+
+ virtual StringRef getData() const = 0;
+
+ // Subclasses can override these methods to provide JIT debugging support
+ virtual void registerWithDebugger() = 0;
+ virtual void deregisterWithDebugger() = 0;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H
+
diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h
index a02cbe2d90..7da4a4e09a 100644
--- a/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -15,12 +15,13 @@
#define LLVM_RUNTIME_DYLD_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
#include "llvm/Support/Memory.h"
namespace llvm {
class RuntimeDyldImpl;
-class MemoryBuffer;
+class ObjectImage;
// RuntimeDyld clients often want to handle the memory management of
// what gets placed where. For JIT clients, this is an abstraction layer
@@ -65,8 +66,11 @@ public:
RuntimeDyld(RTDyldMemoryManager*);
~RuntimeDyld();
- /// Load an in-memory object file into the dynamic linker.
- bool loadObject(MemoryBuffer *InputBuffer);
+ /// loadObject - prepare the object contained in the input buffer for
+ /// execution. Ownership of the input buffer is transferred to the
+ /// ObjectImage instance returned from this function if successful.
+ /// In the case of load failure, the input buffer will be deleted.
+ ObjectImage *loadObject(ObjectBuffer *InputBuffer);
/// Get the address of our local copy of the symbol. This may or may not
/// be the address used for relocation (clients can copy the data around
diff --git a/include/llvm/Function.h b/include/llvm/Function.h
index fa6d0d3f5b..5601c471f2 100644
--- a/include/llvm/Function.h
+++ b/include/llvm/Function.h
@@ -195,16 +195,17 @@ public:
void setGC(const char *Str);
void clearGC();
+
+ /// getRetAttributes - Return the return attributes for querying.
+ Attributes getRetAttributes() const {
+ return AttributeList.getRetAttributes();
+ }
+
/// getParamAttributes - Return the parameter attributes for querying.
Attributes getParamAttributes(unsigned Idx) const {
return AttributeList.getParamAttributes(Idx);
}
- /// @brief Determine whether the function has the given attribute.
- bool paramHasAttr(unsigned i, Attributes attr) const {
- return AttributeList.paramHasAttr(i, attr);
- }
-
/// addAttribute - adds the attribute to the list of attributes.
void addAttribute(unsigned i, Attributes attr);
@@ -218,7 +219,7 @@ public:
/// @brief Determine if the function does not access memory.
bool doesNotAccessMemory() const {
- return getFnAttributes().hasReadNoneAttr();
+ return getFnAttributes().hasAttribute(Attributes::ReadNone);
}
void setDoesNotAccessMemory(bool DoesNotAccessMemory = true) {
if (DoesNotAccessMemory) addFnAttr(Attribute::ReadNone);
@@ -227,7 +228,8 @@ public:
/// @brief Determine if the function does not access or only reads memory.
bool onlyReadsMemory() const {
- return doesNotAccessMemory() || getFnAttributes().hasReadOnlyAttr();
+ return doesNotAccessMemory() ||
+ getFnAttributes().hasAttribute(Attributes::ReadOnly);
}
void setOnlyReadsMemory(bool OnlyReadsMemory = true) {
if (OnlyReadsMemory) addFnAttr(Attribute::ReadOnly);
@@ -236,7 +238,7 @@ public:
/// @brief Determine if the function cannot return.
bool doesNotReturn() const {
- return getFnAttributes().hasNoReturnAttr();
+ return getFnAttributes().hasAttribute(Attributes::NoReturn);
}
void setDoesNotReturn(bool DoesNotReturn = true) {
if (DoesNotReturn) addFnAttr(Attribute::NoReturn);
@@ -245,7 +247,7 @@ public:
/// @brief Determine if the function cannot unwind.
bool doesNotThrow() const {
- return getFnAttributes().hasNoUnwindAttr();
+ return getFnAttributes().hasAttribute(Attributes::NoUnwind);
}
void setDoesNotThrow(bool DoesNotThrow = true) {
if (DoesNotThrow) addFnAttr(Attribute::NoUnwind);
@@ -255,7 +257,7 @@ public:
/// @brief True if the ABI mandates (or the user requested) that this
/// function be in a unwind table.
bool hasUWTable() const {
- return getFnAttributes().hasUWTableAttr();
+ return getFnAttributes().hasAttribute(Attributes::UWTable);
}
void setHasUWTable(bool HasUWTable = true) {
if (HasUWTable)
@@ -272,14 +274,13 @@ public:
/// @brief Determine if the function returns a structure through first
/// pointer argument.
bool hasStructRetAttr() const {
- return getParamAttributes(1).hasStructRetAttr();
+ return getParamAttributes(1).hasAttribute(Attributes::StructRet);
}
/// @brief Determine if the parameter does not alias other parameters.
/// @param n The parameter to check. 1 is the first parameter, 0 is the return
bool doesNotAlias(unsigned n) const {
- return n != 0 ? getParamAttributes(n).hasNoAliasAttr() :
- AttributeList.getRetAttributes().hasNoAliasAttr();
+ return getParamAttributes(n).hasAttribute(Attributes::NoAlias);
}
void setDoesNotAlias(unsigned n, bool DoesNotAlias = true) {
if (DoesNotAlias) addAttribute(n, Attribute::NoAlias);
@@ -289,7 +290,7 @@ public:
/// @brief Determine if the parameter can be captured.
/// @param n The parameter to check. 1 is the first parameter, 0 is the return
bool doesNotCapture(unsigned n) const {
- return getParamAttributes(n).hasNoCaptureAttr();
+ return getParamAttributes(n).hasAttribute(Attributes::NoCapture);
}
void setDoesNotCapture(unsigned n, bool DoesNotCapture = true) {
if (DoesNotCapture) addAttribute(n, Attribute::NoCapture);
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
index 87899fc360..bfdf9c9f01 100644
--- a/include/llvm/InitializePasses.h
+++ b/include/llvm/InitializePasses.h
@@ -246,7 +246,7 @@ void initializeStrongPHIEliminationPass(PassRegistry&);
void initializeTailCallElimPass(PassRegistry&);
void initializeTailDuplicatePassPass(PassRegistry&);
void initializeTargetPassConfigPass(PassRegistry&);
-void initializeTargetDataPass(PassRegistry&);
+void initializeDataLayoutPass(PassRegistry&);
void initializeTargetLibraryInfoPass(PassRegistry&);
void initializeTwoAddressInstructionPassPass(PassRegistry&);
void initializeTypeBasedAliasAnalysisPass(PassRegistry&);
diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h
index e957d759e7..bda9d79da7 100644
--- a/include/llvm/InstrTypes.h
+++ b/include/llvm/InstrTypes.h
@@ -563,7 +563,7 @@ public:
/// IntPtrTy argument is used to make accurate determinations for casts
/// involving Integer and Pointer types. They are no-op casts if the integer
/// is the same size as the pointer. However, pointer size varies with
- /// platform. Generally, the result of TargetData::getIntPtrType() should be
+ /// platform. Generally, the result of DataLayout::getIntPtrType() should be
/// passed in. If that's not available, use Type::Int64Ty, which will make
/// the isNoopCast call conservative.
/// @brief Determine if the described cast is a no-op cast.
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h
index 7a0379e371..17b75b077f 100644
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -1267,13 +1267,11 @@ public:
/// removeAttribute - removes the attribute from the list of attributes.
void removeAttribute(unsigned i, Attributes attr);
- /// \brief Return true if this call has the given attribute.
- bool hasFnAttr(Attributes N) const {
- return paramHasAttr(~0, N);
- }
+ /// @brief Determine whether this call has the given attribute.
+ bool hasFnAttr(Attributes::AttrVal A) const;
- /// @brief Determine whether the call or the callee has the given attribute.
- bool paramHasAttr(unsigned i, Attributes attr) const;
+ /// @brief Determine whether the call or the callee has the given attributes.
+ bool paramHasAttr(unsigned i, Attributes::AttrVal A) const;
/// @brief Extract the alignment for a call or parameter (0=unknown).
unsigned getParamAlignment(unsigned i) const {
@@ -1281,7 +1279,7 @@ public:
}
/// @brief Return true if the call should not be inlined.
- bool isNoInline() const { return hasFnAttr(Attribute::NoInline); }
+ bool isNoInline() const { return hasFnAttr(Attributes::NoInline); }
void setIsNoInline(bool Value = true) {
if (Value) addAttribute(~0, Attribute::NoInline);
else removeAttribute(~0, Attribute::NoInline);
@@ -1289,7 +1287,7 @@ public:
/// @brief Return true if the call can return twice
bool canReturnTwice() const {
- return hasFnAttr(Attribute::ReturnsTwice);
+ return hasFnAttr(Attributes::ReturnsTwice);
}
void setCanReturnTwice(bool Value = true) {
if (Value) addAttribute(~0, Attribute::ReturnsTwice);
@@ -1298,7 +1296,7 @@ public:
/// @brief Determine if the call does not access memory.
bool doesNotAccessMemory() const {
- return hasFnAttr(Attribute::ReadNone);
+ return hasFnAttr(Attributes::ReadNone);
}
void setDoesNotAccessMemory(bool NotAccessMemory = true) {
if (NotAccessMemory) addAttribute(~0, Attribute::ReadNone);
@@ -1307,7 +1305,7 @@ public:
/// @brief Determine if the call does not access or only reads memory.
bool onlyReadsMemory() const {
- return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly);
+ return doesNotAccessMemory() || hasFnAttr(Attributes::ReadOnly);
}
void setOnlyReadsMemory(bool OnlyReadsMemory = true) {
if (OnlyReadsMemory) addAttribute(~0, Attribute::ReadOnly);
@@ -1315,14 +1313,14 @@ public:
}
/// @brief Determine if the call cannot return.
- bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); }
+ bool doesNotReturn() const { return hasFnAttr(Attributes::NoReturn); }
void setDoesNotReturn(bool DoesNotReturn = true) {
if (DoesNotReturn) addAttribute(~0, Attribute::NoReturn);
else removeAttribute(~0, Attribute::NoReturn);
}
/// @brief Determine if the call cannot unwind.
- bool doesNotThrow() const { return hasFnAttr(Attribute::NoUnwind); }
+ bool doesNotThrow() const { return hasFnAttr(Attributes::NoUnwind); }
void setDoesNotThrow(bool DoesNotThrow = true) {
if (DoesNotThrow) addAttribute(~0, Attribute::NoUnwind);
else removeAttribute(~0, Attribute::NoUnwind);
@@ -1332,12 +1330,15 @@ public:
/// pointer argument.
bool hasStructRetAttr() const {
// Be friendly and also check the callee.
- return paramHasAttr(1, Attribute::StructRet);
+ return paramHasAttr(1, Attributes::StructRet);
}
/// @brief Determine if any call argument is an aggregate passed by value.
bool hasByValArgument() const {
- return AttributeList.hasAttrSomewhere(Attribute::ByVal);
+ for (unsigned I = 0, E = AttributeList.getNumAttrs(); I != E; ++I)
+ if (AttributeList.getAttributesAtIndex(I).hasAttribute(Attributes::ByVal))
+ return true;
+ return false;
}
/// getCalledFunction - Return the function called, or null if this is an
@@ -3029,13 +3030,11 @@ public:
/// removeAttribute - removes the attribute from the list of attributes.
void removeAttribute(unsigned i, Attributes attr);
- /// \brief Return true if this call has the given attribute.
- bool hasFnAttr(Attributes N) const {
- return paramHasAttr(~0, N);
- }
+ /// @brief Determine whether this call has the NoAlias attribute.
+ bool hasFnAttr(Attributes::AttrVal A) const;
- /// @brief Determine whether the call or the callee has the given attribute.
- bool paramHasAttr(unsigned i, Attributes attr) const;
+ /// @brief Determine whether the call or the callee has the given attributes.
+ bool paramHasAttr(unsigned i, Attributes::AttrVal A) const;
/// @brief Extract the alignment for a call or parameter (0=unknown).
unsigned getParamAlignment(unsigned i) const {
@@ -3043,7 +3042,7 @@ public:
}
/// @brief Return true if the call should not be inlined.
- bool isNoInline() const { return hasFnAttr(Attribute::NoInline); }
+ bool isNoInline() const { return hasFnAttr(Attributes::NoInline); }
void setIsNoInline(bool Value = true) {
if (Value) addAttribute(~0, Attribute::NoInline);
else removeAttribute(~0, Attribute::NoInline);
@@ -3051,7 +3050,7 @@ public:
/// @brief Determine if the call does not access memory.
bool doesNotAccessMemory() const {
- return hasFnAttr(Attribute::ReadNone);
+ return hasFnAttr(Attributes::ReadNone);
}
void setDoesNotAccessMemory(bool NotAccessMemory = true) {
if (NotAccessMemory) addAttribute(~0, Attribute::ReadNone);
@@ -3060,7 +3059,7 @@ public:
/// @brief Determine if the call does not access or only reads memory.
bool onlyReadsMemory() const {
- return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly);
+ return doesNotAccessMemory() || hasFnAttr(Attributes::ReadOnly);
}
void setOnlyReadsMemory(bool OnlyReadsMemory = true) {
if (OnlyReadsMemory) addAttribute(~0, Attribute::ReadOnly);
@@ -3068,14 +3067,14 @@ public:
}
/// @brief Determine if the call cannot return.
- bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); }
+ bool doesNotReturn() const { return hasFnAttr(Attributes::NoReturn); }
void setDoesNotReturn(bool DoesNotReturn = true) {
if (DoesNotReturn) addAttribute(~0, Attribute::NoReturn);
else removeAttribute(~0, Attribute::NoReturn);
}
/// @brief Determine if the call cannot unwind.
- bool doesNotThrow() const { return hasFnAttr(Attribute::NoUnwind); }
+ bool doesNotThrow() const { return hasFnAttr(Attributes::NoUnwind); }
void setDoesNotThrow(bool DoesNotThrow = true) {
if (DoesNotThrow) addAttribute(~0, Attribute::NoUnwind);
else removeAttribute(~0, Attribute::NoUnwind);
@@ -3085,12 +3084,15 @@ public:
/// pointer argument.
bool hasStructRetAttr() const {
// Be friendly and also check the callee.
- return paramHasAttr(1, Attribute::StructRet);
+ return paramHasAttr(1, Attributes::StructRet);
}
/// @brief Determine if any call argument is an aggregate passed by value.
bool hasByValArgument() const {
- return AttributeList.hasAttrSomewhere(Attribute::ByVal);
+ for (unsigned I = 0, E = AttributeList.getNumAttrs(); I != E; ++I)
+ if (AttributeList.getAttributesAtIndex(I).hasAttribute(Attributes::ByVal))
+ return true;
+ return false;
}
/// getCalledFunction - Return the function called, or null if this is an
diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h
index ebe5542555..f5ca3d5471 100644
--- a/include/llvm/MC/MCAsmBackend.h
+++ b/include/llvm/MC/MCAsmBackend.h
@@ -37,6 +37,7 @@ protected: // Can only create subclasses.
MCAsmBackend();
unsigned HasReliableSymbolDifference : 1;
+ unsigned HasDataInCodeSupport : 1;
public:
virtual ~MCAsmBackend();
@@ -66,6 +67,12 @@ public:
return HasReliableSymbolDifference;
}
+ /// hasDataInCodeSupport - Check whether this target implements data-in-code
+ /// markers. If not, data region directives will be ignored.
+ bool hasDataInCodeSupport() const {
+ return HasDataInCodeSupport;
+ }
+
/// doesSectionRequireSymbols - Check whether the given section requires that
/// all symbols (even temporaries) have symbol table entries.
virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h
index 74e2263c73..23e5513ae3 100644
--- a/include/llvm/MC/MCObjectFileInfo.h
+++ b/include/llvm/MC/MCObjectFileInfo.h
@@ -84,7 +84,8 @@ protected:
/// this is the section to emit them into.
const MCSection *CompactUnwindSection;
- /// DwarfAccelNamesSection, DwarfAccelObjCSection
+ /// DwarfAccelNamesSection, DwarfAccelObjCSection,
+ /// DwarfAccelNamespaceSection, DwarfAccelTypesSection -
/// If we use the DWARF accelerated hash tables then we want toe emit these
/// sections.
const MCSection *DwarfAccelNamesSection;
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index 466773bc0a..d9f72b7f42 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -80,6 +80,13 @@ public:
virtual void ChangeSection(const MCSection *Section);
virtual void EmitInstruction(const MCInst &Inst);
virtual void EmitInstToFragment(const MCInst &Inst);
+ virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
+ virtual void EmitValueToAlignment(unsigned ByteAlignment,
+ int64_t Value = 0,
+ unsigned ValueSize = 1,
+ unsigned MaxBytesToEmit = 0);
+ virtual void EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit = 0);
virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value);
virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
const MCSymbol *LastLabel,
@@ -89,6 +96,8 @@ public:
const MCSymbol *Label);
virtual void EmitGPRel32Value(const MCExpr *Value);
virtual void EmitGPRel64Value(const MCExpr *Value);
+ virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
+ unsigned AddrSpace);
virtual void FinishImpl();
/// @}
diff --git a/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
index 369bc72ff6..0ce32d617e 100644
--- a/include/llvm/MC/MCParser/MCParsedAsmOperand.h
+++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
@@ -29,6 +29,8 @@ public:
virtual bool isImm() const = 0;
/// isReg - Is this a register operand?
virtual bool isReg() const = 0;
+ virtual unsigned getReg() const = 0;
+
/// isMem - Is this a memory operand?
virtual bool isMem() const = 0;
diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h
index 2b5a672d6d..a966a6b8b3 100644
--- a/include/llvm/MC/MCTargetAsmParser.h
+++ b/include/llvm/MC/MCTargetAsmParser.h
@@ -50,6 +50,12 @@ public:
virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
SMLoc &EndLoc) = 0;
+ /// MapAndConstraints - Map inline assembly operands to MCInst operands
+ /// and an associated constraint.
+ typedef std::pair< unsigned, std::string > MapAndConstraint;
+ typedef SmallVector<MapAndConstraint, 4> MatchInstMapAndConstraints;
+ typedef SmallVectorImpl<MapAndConstraint> MatchInstMapAndConstraintsImpl;
+
/// ParseInstruction - Parse one assembly instruction.
///
/// The parser is positioned following the instruction name. The target
@@ -89,11 +95,11 @@ public:
/// On failure, the target parser is responsible for emitting a diagnostic
/// explaining the match failure.
virtual bool
- MatchInstruction(SMLoc IDLoc, unsigned &Kind,
+ MatchInstruction(SMLoc IDLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
- SmallVectorImpl<MCInst> &MCInsts,
- unsigned &OrigErrorInfo,
- bool matchingInlineAsm = false) {
+ MCStreamer &Out, unsigned &Kind, unsigned &Opcode,
+ MatchInstMapAndConstraintsImpl &MapAndConstraints,
+ unsigned &OrigErrorInfo, bool matchingInlineAsm = false) {
OrigErrorInfo = ~0x0;
return true;
}
@@ -115,10 +121,9 @@ public:
return Match_Success;
}
- virtual unsigned getMCInstOperandNum(unsigned Kind,
+ virtual void convertToMapAndConstraints(unsigned Kind,
const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
- unsigned OperandNum,
- unsigned &NumMCOperands) = 0;
+ MatchInstMapAndConstraintsImpl &MapAndConstraints) = 0;
};
} // End llvm namespace
diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h
index 87c5fd3969..57f0518cbf 100644
--- a/include/llvm/MC/SubtargetFeature.h
+++ b/include/llvm/MC/SubtargetFeature.h
@@ -95,10 +95,6 @@ public:
const SubtargetFeatureKV *FeatureTable,
size_t FeatureTableSize);
- /// Get scheduling itinerary of a CPU.
- const void *getItinerary(const StringRef CPU,
- const SubtargetInfoKV *Table, size_t TableSize);
-
/// Print feature string.
void print(raw_ostream &OS) const;
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
index 2e6a7d8c1f..8391e6504c 100644
--- a/include/llvm/Object/ELF.h
+++ b/include/llvm/Object/ELF.h
@@ -413,6 +413,35 @@ struct Elf_Ehdr_Impl {
};
template<support::endianness target_endianness, bool is64Bits>
+struct Elf_Phdr;
+
+template<support::endianness target_endianness>
+struct Elf_Phdr<target_endianness, false> {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, 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
+ Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
+ Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
+ Elf_Word p_memsz; // Num. of bytes in mem image of segment (may be zero)
+ Elf_Word p_flags; // Segment flags
+ Elf_Word p_align; // Segment alignment constraint
+};
+
+template<support::endianness target_endianness>
+struct Elf_Phdr<target_endianness, true> {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, 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
+ Elf_Addr p_vaddr; // Virtual Address of beginning of segment
+ Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
+ Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
+ Elf_Word p_memsz; // Num. of bytes in mem image of segment (may be zero)
+ Elf_Word p_align; // Segment alignment constraint
+};
+
+template<support::endianness target_endianness, bool is64Bits>
class ELFObjectFile : public ObjectFile {
LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
@@ -2272,6 +2301,8 @@ StringRef ELFObjectFile<target_endianness, is64Bits>
return "ELF64-i386";
case ELF::EM_X86_64:
return "ELF64-x86-64";
+ case ELF::EM_PPC64:
+ return "ELF64-ppc64";
default:
return "ELF64-unknown";
}
@@ -2295,6 +2326,8 @@ unsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const {
case ELF::EM_MIPS:
return (target_endianness == support::little) ?
Triple::mipsel : Triple::mips;
+ case ELF::EM_PPC64:
+ return Triple::ppc64;
default:
return Triple::UnknownArch;
}
diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h
index 8905e1e33b..1b25897646 100644
--- a/include/llvm/Support/CallSite.h
+++ b/include/llvm/Support/CallSite.h
@@ -185,13 +185,13 @@ public:
}
/// \brief Return true if this function has the given attribute.
- bool hasFnAttr(Attributes N) const {
- CALLSITE_DELEGATE_GETTER(hasFnAttr(N));
+ bool hasFnAttr(Attributes::AttrVal A) const {
+ CALLSITE_DELEGATE_GETTER(hasFnAttr(A));
}
- /// paramHasAttr - whether the call or the callee has the given attribute.
- bool paramHasAttr(uint16_t i, Attributes attr) const {
- CALLSITE_DELEGATE_GETTER(paramHasAttr(i, attr));
+ /// \brief Return true if the call or the callee has the given attribute.
+ bool paramHasAttr(unsigned i, Attributes::AttrVal A) const {
+ CALLSITE_DELEGATE_GETTER(paramHasAttr(i, A));
}
/// @brief Extract the alignment for a call or parameter (0=unknown).
@@ -244,12 +244,12 @@ public:
/// @brief Determine whether this argument is not captured.
bool doesNotCapture(unsigned ArgNo) const {
- return paramHasAttr(ArgNo + 1, Attribute::NoCapture);
+ return paramHasAttr(ArgNo + 1, Attributes::NoCapture);
}
/// @brief Determine whether this argument is passed by value.
bool isByValArgument(unsigned ArgNo) const {
- return paramHasAttr(ArgNo + 1, Attribute::ByVal);
+ return paramHasAttr(ArgNo + 1, Attributes::ByVal);
}
/// hasArgument - Returns true if this CallSite passes the given Value* as an
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index d0c304712a..8f7d879f2e 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -41,16 +41,14 @@ namespace cl {
// ParseCommandLineOptions - Command line option processing entry point.
//
void ParseCommandLineOptions(int argc, const char * const *argv,
- const char *Overview = 0,
- bool ReadResponseFiles = false);
+ const char *Overview = 0);
//===----------------------------------------------------------------------===//
// ParseEnvironmentOptions - Environment variable option processing alternate
// entry point.
//
void ParseEnvironmentOptions(const char *progName, const char *envvar,
- const char *Overview = 0,
- bool ReadResponseFiles = false);
+ const char *Overview = 0);
///===---------------------------------------------------------------------===//
/// SetVersionPrinter - Override the default (LLVM specific) version printer
diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h
index a02db2fe66..45f7816336 100644
--- a/include/llvm/Support/TargetFolder.h
+++ b/include/llvm/Support/TargetFolder.h
@@ -26,11 +26,11 @@
namespace llvm {
-class TargetData;
+class DataLayout;
/// TargetFolder - Create constants with target dependent folding.
class TargetFolder {
- const TargetData *TD;
+ const DataLayout *TD;
/// Fold - Fold the constant using target specific information.
Constant *Fold(Constant *C) const {
@@ -41,7 +41,7 @@ class TargetFolder {
}
public:
- explicit TargetFolder(const TargetData *TheTD) : TD(TheTD) {}
+ explicit TargetFolder(const DataLayout *TheTD) : TD(TheTD) {}
//===--------------------------------------------------------------------===//
// Binary Operators
diff --git a/include/llvm/TableGen/Main.h b/include/llvm/TableGen/Main.h
index deaef4a990..6b51e20146 100644
--- a/include/llvm/TableGen/Main.h
+++ b/include/llvm/TableGen/Main.h
@@ -16,10 +16,13 @@
namespace llvm {
-class TableGenAction;
+class RecordKeeper;
+class raw_ostream;
+/// \brief Perform the action using Records, and write output to OS.
+/// \returns true on error, false otherwise
+typedef bool TableGenMainFn(raw_ostream &OS, RecordKeeper &Records);
-/// Run the table generator, performing the specified Action on parsed records.
-int TableGenMain(char *argv0, TableGenAction &Action);
+int TableGenMain(char *argv0, TableGenMainFn *MainFn);
}
diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h
index 8c4893dd04..079dc8ce8e 100644
--- a/include/llvm/TableGen/Record.h
+++ b/include/llvm/TableGen/Record.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
@@ -66,10 +67,28 @@ class RecordKeeper;
//===----------------------------------------------------------------------===//
class RecTy {
+public:
+ /// \brief Subclass discriminator (for dyn_cast<> et al.)
+ enum RecTyKind {
+ BitRecTyKind,
+ BitsRecTyKind,
+ IntRecTyKind,
+ StringRecTyKind,
+ ListRecTyKind,
+ DagRecTyKind,
+ RecordRecTyKind
+ };
+
+private:
+ RecTyKind Kind;
ListRecTy *ListTy;
virtual void anchor();
+
public:
- RecTy() : ListTy(0) {}
+ static bool classof(const RecTy *) { return true; }
+ RecTyKind getRecTyKind() const { return Kind; }
+
+ RecTy(RecTyKind K) : Kind(K), ListTy(0) {}
virtual ~RecTy() {}
virtual std::string getAsString() const = 0;
@@ -132,8 +151,13 @@ inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) {
///
class BitRecTy : public RecTy {
static BitRecTy Shared;
- BitRecTy() {}
+ BitRecTy() : RecTy(BitRecTyKind) {}
public:
+ static bool classof(const BitRecTy *) { return true; }
+ static bool classof(const RecTy *RT) {
+ return RT->getRecTyKind() == BitRecTyKind;
+ }
+
static BitRecTy *get() { return &Shared; }
virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
@@ -173,8 +197,13 @@ public:
///
class BitsRecTy : public RecTy {
unsigned Size;
- explicit BitsRecTy(unsigned Sz) : Size(Sz) {}
+ explicit BitsRecTy(unsigned Sz) : RecTy(BitsRecTyKind), Size(Sz) {}
public:
+ static bool classof(const BitsRecTy *) { return true; }
+ static bool classof(const RecTy *RT) {
+ return RT->getRecTyKind() == BitsRecTyKind;
+ }
+
static BitsRecTy *get(unsigned Sz);
unsigned getNumBits() const { return Size; }
@@ -217,8 +246,13 @@ public:
///
class IntRecTy : public RecTy {
static IntRecTy Shared;
- IntRecTy() {}
+ IntRecTy() : RecTy(IntRecTyKind) {}
public:
+ static bool classof(const IntRecTy *) { return true; }
+ static bool classof(const RecTy *RT) {
+ return RT->getRecTyKind() == IntRecTyKind;
+ }
+
static IntRecTy *get() { return &Shared; }
virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
@@ -257,8 +291,13 @@ public:
///
class StringRecTy : public RecTy {
static StringRecTy Shared;
- StringRecTy() {}
+ StringRecTy() : RecTy(StringRecTyKind) {}
public:
+ static bool classof(const StringRecTy *) { return true; }
+ static bool classof(const RecTy *RT) {
+ return RT->getRecTyKind() == StringRecTyKind;
+ }
+
static StringRecTy *get() { return &Shared; }
virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
@@ -300,9 +339,14 @@ public:
///
class ListRecTy : public RecTy {
RecTy *Ty;
- explicit ListRecTy(RecTy *T) : Ty(T) {}
+ explicit ListRecTy(RecTy *T) : RecTy(ListRecTyKind), Ty(T) {}
friend ListRecTy *RecTy::getListTy();
public:
+ static bool classof(const ListRecTy *) { return true; }
+ static bool classof(const RecTy *RT) {
+ return RT->getRecTyKind() == ListRecTyKind;
+ }
+
static ListRecTy *get(RecTy *T) { return T->getListTy(); }
RecTy *getElementType() const { return Ty; }
@@ -343,8 +387,13 @@ public:
///
class DagRecTy : public RecTy {
static DagRecTy Shared;
- DagRecTy() {}
+ DagRecTy() : RecTy(DagRecTyKind) {}
public:
+ static bool classof(const DagRecTy *) { return true; }
+ static bool classof(const RecTy *RT) {
+ return RT->getRecTyKind() == DagRecTyKind;
+ }
+
static DagRecTy *get() { return &Shared; }
virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
@@ -384,9 +433,14 @@ public:
///
class RecordRecTy : public RecTy {
Record *Rec;
- explicit RecordRecTy(Record *R) : Rec(R) {}
+ explicit RecordRecTy(Record *R) : RecTy(RecordRecTyKind), Rec(R) {}
friend class Record;
public:
+ static bool classof(const RecordRecTy *) { return true; }
+ static bool classof(const RecTy *RT) {
+ return RT->getRecTyKind() == RecordRecTyKind;
+ }
+
static RecordRecTy *get(Record *R);
Record *getRecord() const { return Rec; }
@@ -1031,9 +1085,9 @@ class VarBitInit : public Init {
VarBitInit(TypedInit *T, unsigned B) : TI(T), Bit(B) {
assert(T->getType() &&
- (dynamic_cast<IntRecTy*>(T->getType()) ||
- (dynamic_cast<BitsRecTy*>(T->getType()) &&
- dynamic_cast<BitsRecTy*>(T->getType())->getNumBits() > B)) &&
+ (isa<IntRecTy>(T->getType()) ||
+ (isa<BitsRecTy>(T->getType()) &&
+ cast<BitsRecTy>(T->getType())->getNumBits() > B)) &&
"Illegal VarBitInit expression!");
}
@@ -1066,9 +1120,9 @@ class VarListElementInit : public TypedInit {
unsigned Element;
VarListElementInit(TypedInit *T, unsigned E)
- : TypedInit(dynamic_cast<ListRecTy*>(T->getType())->getElementType()),
+ : TypedInit(cast<ListRecTy>(T->getType())->getElementType()),
TI(T), Element(E) {
- assert(T->getType() && dynamic_cast<ListRecTy*>(T->getType()) &&
+ assert(T->getType() && isa<ListRecTy>(T->getType()) &&
"Illegal VarBitInit expression!");
}
diff --git a/include/llvm/TableGen/TableGenAction.h b/include/llvm/TableGen/TableGenAction.h
deleted file mode 100644
index 733ae62644..0000000000
--- a/include/llvm/TableGen/TableGenAction.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===- llvm/TableGen/TableGenAction.h - defines TableGenAction --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the TableGenAction base class to be derived from by
-// tblgen tools.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TABLEGEN_TABLEGENACTION_H
-#define LLVM_TABLEGEN_TABLEGENACTION_H
-
-namespace llvm {
-
-class raw_ostream;
-class RecordKeeper;
-
-class TableGenAction {
- virtual void anchor();
-public:
- virtual ~TableGenAction() {}
-
- /// Perform the action using Records, and write output to OS.
- /// @returns true on error, false otherwise
- virtual bool operator()(raw_ostream &OS, RecordKeeper &Records) = 0;
-};
-
-}
-
-#endif
diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h
index d5e165e58b..a50f54a436 100644
--- a/include/llvm/Target/Mangler.h
+++ b/include/llvm/Target/Mangler.h
@@ -22,7 +22,7 @@ class GlobalValue;
template <typename T> class SmallVectorImpl;
class MCContext;
class MCSymbol;
-class TargetData;
+class DataLayout;
class Mangler {
public:
@@ -34,7 +34,7 @@ public:
private:
MCContext &Context;
- const TargetData &TD;
+ const DataLayout &TD;
/// AnonGlobalIDs - We need to give global values the same name every time
/// they are mangled. This keeps track of the number we give to anonymous
@@ -47,20 +47,19 @@ private:
unsigned NextAnonGlobalID;
public:
- Mangler(MCContext &context, const TargetData &td)
+ Mangler(MCContext &context, const DataLayout &td)
: Context(context), TD(td), NextAnonGlobalID(1) {}
/// getSymbol - Return the MCSymbol for the specified global value. This
/// symbol is the main label that is the address of the global.
MCSymbol *getSymbol(const GlobalValue *GV);
-
/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
/// and the specified global variable's name. If the global variable doesn't
/// have a name, this fills in a unique name for the global.
void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV,
bool isImplicitlyPrivate);
-
+
/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
/// and the specified name as the global variable name. GVName must not be
/// empty.
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index a78ef58b88..bf81d1a68f 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -22,6 +22,7 @@
#ifndef LLVM_TARGET_TARGETLOWERING_H
#define LLVM_TARGET_TARGETLOWERING_H
+#include "llvm/AddressingMode.h"
#include "llvm/CallingConv.h"
#include "llvm/InlineAsm.h"
#include "llvm/Attributes.h"
@@ -50,7 +51,7 @@ namespace llvm {
class MCContext;
class MCExpr;
template<typename T> class SmallVectorImpl;
- class TargetData;
+ class DataLayout;
class TargetRegisterClass;
class TargetLibraryInfo;
class TargetLoweringObjectFile;
@@ -149,12 +150,15 @@ public:
virtual ~TargetLowering();
const TargetMachine &getTargetMachine() const { return TM; }
- const TargetData *getTargetData() const { return TD; }
+ const DataLayout *getDataLayout() const { return TD; }
const TargetLoweringObjectFile &getObjFileLowering() const { return TLOF; }
bool isBigEndian() const { return !IsLittleEndian; }
bool isLittleEndian() const { return IsLittleEndian; }
- MVT getPointerTy() const { return PointerTy; }
+ // Return the pointer type for the given address space, defaults to
+ // the pointer type from the data layout.
+ // FIXME: The default needs to be removed once all the code is updated.
+ virtual MVT getPointerTy(uint32_t addrspace = 0) const { return PointerTy; }
virtual MVT getShiftAmountTy(EVT LHSTy) const;
/// isSelectExpensive - Return true if the select operation is expensive for
@@ -169,12 +173,12 @@ public:
/// isSlowDivBypassed - Returns true if target has indicated at least one
/// type should be bypassed.
- bool isSlowDivBypassed() const { return !BypassSlowDivTypes.empty(); }
+ bool isSlowDivBypassed() const { return !BypassSlowDivWidths.empty(); }
/// getBypassSlowDivTypes - Returns map of slow types for division or
/// remainder with corresponding fast types
- const DenseMap<Type *, Type *> &getBypassSlowDivTypes() const {
- return BypassSlowDivTypes;
+ const DenseMap<unsigned int, unsigned int> &getBypassSlowDivWidths() const {
+ return BypassSlowDivWidths;
}
/// isPow2DivCheap() - Return true if pow2 div is cheaper than a chain of
@@ -1095,9 +1099,9 @@ protected:
/// of instructions not containing an integer divide.
void setIntDivIsCheap(bool isCheap = true) { IntDivIsCheap = isCheap; }
- /// addBypassSlowDivType - Tells the code generator which types to bypass.
- void addBypassSlowDivType(Type *slow_type, Type *fast_type) {
- BypassSlowDivTypes[slow_type] = fast_type;
+ /// addBypassSlowDiv - Tells the code generator which bitwidths to bypass.
+ void addBypassSlowDiv(unsigned int SlowBitWidth, unsigned int FastBitWidth) {
+ BypassSlowDivWidths[SlowBitWidth] = FastBitWidth;
}
/// setPow2DivIsCheap - Tells the code generator that it shouldn't generate
@@ -1331,9 +1335,9 @@ public:
FunctionType *FTy, bool isTailCall, SDValue callee,
ArgListTy &args, SelectionDAG &dag, DebugLoc dl,
ImmutableCallSite &cs)
- : Chain(chain), RetTy(retTy), RetSExt(cs.paramHasAttr(0, Attribute::SExt)),
- RetZExt(cs.paramHasAttr(0, Attribute::ZExt)), IsVarArg(FTy->isVarArg()),
- IsInReg(cs.paramHasAttr(0, Attribute::InReg)),
+ : Chain(chain), RetTy(retTy), RetSExt(cs.paramHasAttr(0, Attributes::SExt)),
+ RetZExt(cs.paramHasAttr(0, Attributes::ZExt)), IsVarArg(FTy->isVarArg()),
+ IsInReg(cs.paramHasAttr(0, Attributes::InReg)),
DoesNotReturn(cs.doesNotReturn()),
IsReturnValueUsed(!cs.getInstruction()->use_empty()),
IsTailCall(isTailCall), NumFixedArgs(FTy->getNumParams()),
@@ -1644,22 +1648,6 @@ public:
// Addressing mode description hooks (used by LSR etc).
//
- /// AddrMode - This represents an addressing mode of:
- /// BaseGV + BaseOffs + BaseReg + Scale*ScaleReg
- /// If BaseGV is null, there is no BaseGV.
- /// If BaseOffs is zero, there is no base offset.
- /// If HasBaseReg is false, there is no base register.
- /// If Scale is zero, there is no ScaleReg. Scale of 1 indicates a reg with
- /// no scale.
- ///
- struct AddrMode {
- GlobalValue *BaseGV;
- int64_t BaseOffs;
- bool HasBaseReg;
- int64_t Scale;
- AddrMode() : BaseGV(0), BaseOffs(0), HasBaseReg(false), Scale(0) {}
- };
-
/// GetAddrModeArguments - CodeGenPrepare sinks address calculations into the
/// same BB as Load/Store instructions reading the address. This allows as
/// much computation as possible to be done in the address mode for that
@@ -1801,10 +1789,11 @@ public:
private:
const TargetMachine &TM;
- const TargetData *TD;
+ const DataLayout *TD;
const TargetLoweringObjectFile &TLOF;
- /// PointerTy - The type to use for pointers, usually i32 or i64.
+ /// PointerTy - The type to use for pointers for the default address space,
+ /// usually i32 or i64.
///
MVT PointerTy;
@@ -1822,11 +1811,11 @@ private:
/// set to true unconditionally.
bool IntDivIsCheap;
- /// BypassSlowDivTypes - Tells the code generator to bypass slow divide or
- /// remainder instructions. For example, SlowDivBypass[i32,u8] tells the code
- /// generator to bypass 32-bit signed integer div/rem with an 8-bit unsigned
+ /// BypassSlowDivMap - Tells the code generator to bypass slow divide or
+ /// remainder instructions. For example, BypassSlowDivWidths[32,8] tells the
+ /// code generator to bypass 32-bit integer div/rem with an 8-bit unsigned
/// integer div/rem when the operands are positive and less than 256.
- DenseMap <Type *, Type *> BypassSlowDivTypes;
+ DenseMap <unsigned int, unsigned int> BypassSlowDivWidths;
/// Pow2DivIsCheap - Tells the code generator that it shouldn't generate
/// srl/add/sra for a signed divide by power of two, and let the target handle
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index b6fa817542..988916f9d9 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -31,7 +31,7 @@ class MCCodeGenInfo;
class MCContext;
class PassManagerBase;
class Target;
-class TargetData;
+class DataLayout;
class TargetELFWriterInfo;
class TargetFrameLowering;
class TargetInstrInfo;
@@ -106,7 +106,7 @@ public:
virtual const TargetFrameLowering *getFrameLowering() const { return 0; }
virtual const TargetLowering *getTargetLowering() const { return 0; }
virtual const TargetSelectionDAGInfo *getSelectionDAGInfo() const{ return 0; }
- virtual const TargetData *getTargetData() const { return 0; }
+ virtual const DataLayout *getDataLayout() const { return 0; }
/// getMCAsmInfo - Return target specific asm information.
///
diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td
index cf3d250590..0da82fdd89 100644
--- a/include/llvm/Target/TargetSchedule.td
+++ b/include/llvm/Target/TargetSchedule.td
@@ -55,6 +55,15 @@ include "llvm/Target/TargetItinerary.td"
class Instruction; // Forward def
+// DAG operator that interprets the DAG args as Instruction defs.
+def instrs;
+
+// DAG operator that interprets each DAG arg as a regex pattern for
+// matching Instruction opcode names.
+// The regex must match the beginning of the opcode (as in Python re.match).
+// To avoid matching prefixes, append '$' to the pattern.
+def instregex;
+
// Define the SchedMachineModel and provide basic properties for
// coarse grained instruction cost model. Default values for the
// properties are defined in MCSchedModel. A value of "-1" in the
@@ -325,9 +334,9 @@ class SchedReadVariant<list<SchedVar> variants> : SchedRead,
// the subtarget to easily override specific operations.
//
// SchedModel ties this opcode mapping to a processor.
-class InstRW<list<SchedReadWrite> rw, list<Instruction> instrs> {
+class InstRW<list<SchedReadWrite> rw, dag instrlist> {
list<SchedReadWrite> OperandReadWrites = rw;
- list<Instruction> Instrs = instrs;
+ dag Instrs = instrlist;
SchedMachineModel SchedModel = ?;
}
diff --git a/include/llvm/Target/TargetSelectionDAGInfo.h b/include/llvm/Target/TargetSelectionDAGInfo.h
index 8c5874e38f..96793bc036 100644
--- a/include/llvm/Target/TargetSelectionDAGInfo.h
+++ b/include/llvm/Target/TargetSelectionDAGInfo.h
@@ -20,7 +20,7 @@
namespace llvm {
-class TargetData;
+class DataLayout;
class TargetMachine;
//===----------------------------------------------------------------------===//
@@ -31,10 +31,10 @@ class TargetSelectionDAGInfo {
TargetSelectionDAGInfo(const TargetSelectionDAGInfo &) LLVM_DELETED_FUNCTION;
void operator=(const TargetSelectionDAGInfo &) LLVM_DELETED_FUNCTION;
- const TargetData *TD;
+ const DataLayout *TD;
protected:
- const TargetData *getTargetData() const { return TD; }
+ const DataLayout *getDataLayout() const { return TD; }
public:
explicit TargetSelectionDAGInfo(const TargetMachine &TM);
diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h
index 08c78f2564..6db96d980b 100644
--- a/include/llvm/Target/TargetSubtargetInfo.h
+++ b/include/llvm/Target/TargetSubtargetInfo.h
@@ -54,12 +54,6 @@ public:
return 0;
}
- /// getSpecialAddressLatency - For targets where it is beneficial to
- /// backschedule instructions that compute addresses, return a value
- /// indicating the number of scheduling cycles of backscheduling that
- /// should be attempted.
- virtual unsigned getSpecialAddressLatency() const { return 0; }
-
// enablePostRAScheduler - If the target can benefit from post-regalloc
// scheduling and the specified optimization level meets the requirement
// return true to enable post-register-allocation scheduling. In
diff --git a/include/llvm/Transforms/IPO/InlinerPass.h b/include/llvm/Transforms/IPO/InlinerPass.h
index 7c3cfc8701..b036040f51 100644
--- a/include/llvm/Transforms/IPO/InlinerPass.h
+++ b/include/llvm/Transforms/IPO/InlinerPass.h
@@ -21,7 +21,7 @@
namespace llvm {
class CallSite;
- class TargetData;
+ class DataLayout;
class InlineCost;
template<class PtrType, unsigned SmallSize>
class SmallPtrSet;
diff --git a/include/llvm/Transforms/Utils/AddrModeMatcher.h b/include/llvm/Transforms/Utils/AddrModeMatcher.h
index 90485eb4c6..7d672839a6 100644
--- a/include/llvm/Transforms/Utils/AddrModeMatcher.h
+++ b/include/llvm/Transforms/Utils/AddrModeMatcher.h
@@ -19,6 +19,7 @@
#ifndef LLVM_TRANSFORMS_UTILS_ADDRMODEMATCHER_H
#define LLVM_TRANSFORMS_UTILS_ADDRMODEMATCHER_H
+#include "llvm/AddressingMode.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Target/TargetLowering.h"
@@ -33,7 +34,7 @@ class raw_ostream;
/// ExtAddrMode - This is an extended version of TargetLowering::AddrMode
/// which holds actual Value*'s for register values.
-struct ExtAddrMode : public TargetLowering::AddrMode {
+struct ExtAddrMode : public AddrMode {
Value *BaseReg;
Value *ScaledReg;
ExtAddrMode() : BaseReg(0), ScaledReg(0) {}
diff --git a/include/llvm/Transforms/Utils/BuildLibCalls.h b/include/llvm/Transforms/Utils/BuildLibCalls.h
index a6e41f0a27..ab9fc475fa 100644
--- a/include/llvm/Transforms/Utils/BuildLibCalls.h
+++ b/include/llvm/Transforms/Utils/BuildLibCalls.h
@@ -19,7 +19,7 @@
namespace llvm {
class Value;
- class TargetData;
+ class DataLayout;
class TargetLibraryInfo;
/// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
@@ -28,52 +28,52 @@ namespace llvm {
/// EmitStrLen - Emit a call to the strlen function to the builder, for the
/// specified pointer. Ptr is required to be some pointer type, and the
/// return value has 'intptr_t' type.
- Value *EmitStrLen(Value *Ptr, IRBuilder<> &B, const TargetData *TD,
+ Value *EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI);
/// EmitStrNLen - Emit a call to the strnlen function to the builder, for the
/// specified pointer. Ptr is required to be some pointer type, MaxLen must
/// be of size_t type, and the return value has 'intptr_t' type.
Value *EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI);
+ const DataLayout *TD, const TargetLibraryInfo *TLI);
/// EmitStrChr - Emit a call to the strchr function to the builder, for the
/// specified pointer and character. Ptr is required to be some pointer type,
/// and the return value has 'i8*' type.
- Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, const TargetData *TD,
+ Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI);
/// EmitStrNCmp - Emit a call to the strncmp function to the builder.
Value *EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI);
+ const DataLayout *TD, const TargetLibraryInfo *TLI);
/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
/// specified pointer arguments.
Value *EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI,
+ const DataLayout *TD, const TargetLibraryInfo *TLI,
StringRef Name = "strcpy");
/// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the
/// specified pointer arguments and length.
Value *EmitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI,
+ const DataLayout *TD, const TargetLibraryInfo *TLI,
StringRef Name = "strncpy");
/// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder.
/// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src
/// are pointers.
Value *EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
- IRBuilder<> &B, const TargetData *TD,
+ IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI);
/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI);
+ const DataLayout *TD, const TargetLibraryInfo *TLI);
/// EmitMemCmp - Emit a call to the memcmp function.
Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI);
+ const DataLayout *TD, const TargetLibraryInfo *TLI);
/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name'
/// (e.g. 'floor'). This function is known to take a single of type matching
@@ -85,28 +85,28 @@ namespace llvm {
/// EmitPutChar - Emit a call to the putchar function. This assumes that Char
/// is an integer.
- Value *EmitPutChar(Value *Char, IRBuilder<> &B, const TargetData *TD,
+ Value *EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI);
/// EmitPutS - Emit a call to the puts function. This assumes that Str is
/// some pointer.
- Value *EmitPutS(Value *Str, IRBuilder<> &B, const TargetData *TD,
+ Value *EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI);
/// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
/// an i32, and File is a pointer to FILE.
Value *EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI);
+ const DataLayout *TD, const TargetLibraryInfo *TLI);
/// EmitFPutS - Emit a call to the puts function. Str is required to be a
/// pointer and File is a pointer to FILE.
- Value *EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, const TargetData *TD,
+ Value *EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI);
/// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is
/// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
Value *EmitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI);
+ const DataLayout *TD, const TargetLibraryInfo *TLI);
/// SimplifyFortifiedLibCalls - Helper class for folding checked library
/// calls (e.g. __strcpy_chk) into their unchecked counterparts.
@@ -118,7 +118,7 @@ namespace llvm {
bool isString) const = 0;
public:
virtual ~SimplifyFortifiedLibCalls();
- bool fold(CallInst *CI, const TargetData *TD, const TargetLibraryInfo *TLI);
+ bool fold(CallInst *CI, const DataLayout *TD, const TargetLibraryInfo *TLI);
};
}
diff --git a/include/llvm/Transforms/Utils/BypassSlowDivision.h b/include/llvm/Transforms/Utils/BypassSlowDivision.h
index dceda48587..ac8af122f0 100644
--- a/include/llvm/Transforms/Utils/BypassSlowDivision.h
+++ b/include/llvm/Transforms/Utils/BypassSlowDivision.h
@@ -26,7 +26,7 @@ namespace llvm {
/// profitably bypassed and carried out with a shorter, faster divide.
bool bypassSlowDivision(Function &F,
Function::iterator &I,
- const DenseMap<Type*, Type*> &BypassTypeMap);
+ const DenseMap<unsigned int, unsigned int> &BypassWidth);
} // End llvm namespace
diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h
index 92e15ce932..1780025a27 100644
--- a/include/llvm/Transforms/Utils/Cloning.h
+++ b/include/llvm/Transforms/Utils/Cloning.h
@@ -39,7 +39,7 @@ class ReturnInst;
class CallSite;
class Trace;
class CallGraph;
-class TargetData;
+class DataLayout;
class Loop;
class LoopInfo;
class AllocaInst;
@@ -150,7 +150,7 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
SmallVectorImpl<ReturnInst*> &Returns,
const char *NameSuffix = "",
ClonedCodeInfo *CodeInfo = 0,
- const TargetData *TD = 0,
+ const DataLayout *TD = 0,
Instruction *TheCall = 0);
@@ -158,13 +158,13 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
/// InlineFunction call, and records the auxiliary results produced by it.
class InlineFunctionInfo {
public:
- explicit InlineFunctionInfo(CallGraph *cg = 0, const TargetData *td = 0)
+ explicit InlineFunctionInfo(CallGraph *cg = 0, const DataLayout *td = 0)
: CG(cg), TD(td) {}
/// CG - If non-null, InlineFunction will update the callgraph to reflect the
/// changes it makes.
CallGraph *CG;
- const TargetData *TD;
+ const DataLayout *TD;
/// StaticAllocas - InlineFunction fills this in with all static allocas that
/// get copied into the caller.
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
index 83f0e7a4bd..21dd3fbe11 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -18,7 +18,7 @@
#include "llvm/IRBuilder.h"
#include "llvm/Operator.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
namespace llvm {
@@ -35,7 +35,7 @@ class Pass;
class PHINode;
class AllocaInst;
class ConstantExpr;
-class TargetData;
+class DataLayout;
class TargetLibraryInfo;
class DIBuilder;
@@ -84,7 +84,7 @@ bool RecursivelyDeleteDeadPHINode(PHINode *PN, const TargetLibraryInfo *TLI=0);
///
/// This returns true if it changed the code, note that it can delete
/// instructions in other blocks as well in this block.
-bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetData *TD = 0,
+bool SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
//===----------------------------------------------------------------------===//
@@ -103,7 +103,7 @@ bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetData *TD = 0,
/// .. and delete the predecessor corresponding to the '1', this will attempt to
/// recursively fold the 'and' to 0.
void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred,
- TargetData *TD = 0);
+ DataLayout *TD = 0);
/// MergeBasicBlockIntoOnlyPred - BB is a block with one predecessor and its
@@ -134,7 +134,7 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB);
/// of the CFG. It returns true if a modification was made, possibly deleting
/// the basic block that was pointed to.
///
-bool SimplifyCFG(BasicBlock *BB, const TargetData *TD = 0);
+bool SimplifyCFG(BasicBlock *BB, const DataLayout *TD = 0);
/// FoldBranchToCommonDest - If this basic block is ONLY a setcc and a branch,
/// and if a predecessor branches to us and one of our successors, fold the
@@ -162,10 +162,10 @@ AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = 0);
/// and it is more than the alignment of the ultimate object, see if we can
/// increase the alignment of the ultimate object, making this check succeed.
unsigned getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign,
- const TargetData *TD = 0);
+ const DataLayout *TD = 0);
/// getKnownAlignment - Try to infer an alignment for the specified pointer.
-static inline unsigned getKnownAlignment(Value *V, const TargetData *TD = 0) {
+static inline unsigned getKnownAlignment(Value *V, const DataLayout *TD = 0) {
return getOrEnforceKnownAlignment(V, 0, TD);
}
@@ -175,7 +175,7 @@ static inline unsigned getKnownAlignment(Value *V, const TargetData *TD = 0) {
/// When NoAssumptions is true, no assumptions about index computation not
/// overflowing is made.
template<typename IRBuilderTy>
-Value *EmitGEPOffset(IRBuilderTy *Builder, const TargetData &TD, User *GEP,
+Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP,
bool NoAssumptions = false) {
gep_type_iterator GTI = gep_type_begin(GEP);
Type *IntPtrTy = TD.getIntPtrType(GEP->getContext());
diff --git a/include/llvm/Type.h b/include/llvm/Type.h
index 185258d8ff..8e66ea8609 100644
--- a/include/llvm/Type.h
+++ b/include/llvm/Type.h
@@ -252,7 +252,7 @@ public:
/// isSized - Return true if it makes sense to take the size of this type. To
/// get the actual size for a particular target, it is reasonable to use the
- /// TargetData subsystem to do this.
+ /// DataLayout subsystem to do this.
///
bool isSized() const {
// If it's a primitive, it is always sized.
@@ -276,7 +276,7 @@ public:
///
/// Note that this may not reflect the size of memory allocated for an
/// instance of the type or the number of bytes that are written when an
- /// instance of the type is stored to memory. The TargetData class provides
+ /// instance of the type is stored to memory. The DataLayout class provides
/// additional query functions to provide this information.
///
unsigned getPrimitiveSizeInBits() const;
diff --git a/include/llvm/User.h b/include/llvm/User.h
index abd80afb70..ade3676260 100644
--- a/include/llvm/User.h
+++ b/include/llvm/User.h
@@ -104,7 +104,7 @@ public:
assert(i < NumOperands && "getOperandUse() out of range!");
return OperandList[i];
}
-
+
unsigned getNumOperands() const { return NumOperands; }
// ---------------------------------------------------------------------------
@@ -118,6 +118,45 @@ public:
inline op_iterator op_end() { return OperandList+NumOperands; }
inline const_op_iterator op_end() const { return OperandList+NumOperands; }
+ /// Convenience iterator for directly iterating over the Values in the
+ /// OperandList
+ class value_op_iterator : public std::iterator<std::forward_iterator_tag,
+ Value*> {
+ op_iterator OI;
+ public:
+ explicit value_op_iterator(Use *U) : OI(U) {}
+
+ bool operator==(const value_op_iterator &x) const {
+ return OI == x.OI;
+ }
+ bool operator!=(const value_op_iterator &x) const {
+ return !operator==(x);
+ }
+
+ /// Iterator traversal: forward iteration only
+ value_op_iterator &operator++() { // Preincrement
+ ++OI;
+ return *this;
+ }
+ value_op_iterator operator++(int) { // Postincrement
+ value_op_iterator tmp = *this; ++*this; return tmp;
+ }
+
+ /// Retrieve a pointer to the current Value.
+ Value *operator*() const {
+ return *OI;
+ }
+
+ Value *operator->() const { return operator*(); }
+ };
+
+ inline value_op_iterator value_op_begin() {
+ return value_op_iterator(op_begin());
+ }
+ inline value_op_iterator value_op_end() {
+ return value_op_iterator(op_end());
+ }
+
// dropAllReferences() - This function is in charge of "letting go" of all
// objects that this User refers to. This allows one to
// 'delete' a whole class at a time, even though there may be circular
diff --git a/lib/Analysis/AliasAnalysis.cpp b/lib/Analysis/AliasAnalysis.cpp
index f768eeca41..752edd52b4 100644
--- a/lib/Analysis/AliasAnalysis.cpp
+++ b/lib/Analysis/AliasAnalysis.cpp
@@ -35,7 +35,7 @@
#include "llvm/Instructions.h"
#include "llvm/LLVMContext.h"
#include "llvm/Type.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
using namespace llvm;
@@ -452,7 +452,7 @@ AliasAnalysis::~AliasAnalysis() {}
/// AliasAnalysis interface before any other methods are called.
///
void AliasAnalysis::InitializeAliasAnalysis(Pass *P) {
- TD = P->getAnalysisIfAvailable<TargetData>();
+ TD = P->getAnalysisIfAvailable<DataLayout>();
TLI = P->getAnalysisIfAvailable<TargetLibraryInfo>();
AA = &P->getAnalysis<AliasAnalysis>();
}
@@ -463,7 +463,7 @@ void AliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<AliasAnalysis>(); // All AA's chain
}
-/// getTypeStoreSize - Return the TargetData store size for the given type,
+/// getTypeStoreSize - Return the DataLayout store size for the given type,
/// if known, or a conservative value otherwise.
///
uint64_t AliasAnalysis::getTypeStoreSize(Type *Ty) {
@@ -503,7 +503,7 @@ bool AliasAnalysis::canInstructionRangeModify(const Instruction &I1,
bool llvm::isNoAliasCall(const Value *V) {
if (isa<CallInst>(V) || isa<InvokeInst>(V))
return ImmutableCallSite(cast<Instruction>(V))
- .paramHasAttr(0, Attribute::NoAlias);
+ .paramHasAttr(0, Attributes::NoAlias);
return false;
}
diff --git a/lib/Analysis/AliasSetTracker.cpp b/lib/Analysis/AliasSetTracker.cpp
index 3199a118eb..388c755cbd 100644
--- a/lib/Analysis/AliasSetTracker.cpp
+++ b/lib/Analysis/AliasSetTracker.cpp
@@ -18,7 +18,7 @@
#include "llvm/LLVMContext.h"
#include "llvm/Pass.h"
#include "llvm/Type.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp
index 7fad8fecb0..263bfc031f 100644
--- a/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/lib/Analysis/BasicAliasAnalysis.cpp
@@ -29,7 +29,7 @@
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
@@ -84,7 +84,7 @@ static bool isEscapeSource(const Value *V) {
/// getObjectSize - Return the size of the object specified by V, or
/// UnknownSize if unknown.
-static uint64_t getObjectSize(const Value *V, const TargetData &TD,
+static uint64_t getObjectSize(const Value *V, const DataLayout &TD,
const TargetLibraryInfo &TLI,
bool RoundToAlign = false) {
uint64_t Size;
@@ -96,7 +96,7 @@ static uint64_t getObjectSize(const Value *V, const TargetData &TD,
/// isObjectSmallerThan - Return true if we can prove that the object specified
/// by V is smaller than Size.
static bool isObjectSmallerThan(const Value *V, uint64_t Size,
- const TargetData &TD,
+ const DataLayout &TD,
const TargetLibraryInfo &TLI) {
// This function needs to use the aligned object size because we allow
// reads a bit past the end given sufficient alignment.
@@ -108,7 +108,7 @@ static bool isObjectSmallerThan(const Value *V, uint64_t Size,
/// isObjectSize - Return true if we can prove that the object specified
/// by V has size Size.
static bool isObjectSize(const Value *V, uint64_t Size,
- const TargetData &TD, const TargetLibraryInfo &TLI) {
+ const DataLayout &TD, const TargetLibraryInfo &TLI) {
uint64_t ObjectSize = getObjectSize(V, TD, TLI);
return ObjectSize != AliasAnalysis::UnknownSize && ObjectSize == Size;
}
@@ -151,7 +151,7 @@ namespace {
/// represented in the result.
static Value *GetLinearExpression(Value *V, APInt &Scale, APInt &Offset,
ExtensionKind &Extension,
- const TargetData &TD, unsigned Depth) {
+ const DataLayout &TD, unsigned Depth) {
assert(V->getType()->isIntegerTy() && "Not an integer value");
// Limit our recursion depth.
@@ -226,14 +226,14 @@ static Value *GetLinearExpression(Value *V, APInt &Scale, APInt &Offset,
/// specified amount, but which may have other unrepresented high bits. As such,
/// the gep cannot necessarily be reconstructed from its decomposed form.
///
-/// When TargetData is around, this function is capable of analyzing everything
+/// When DataLayout is around, this function is capable of analyzing everything
/// that GetUnderlyingObject can look through. When not, it just looks
/// through pointer casts.
///
static const Value *
DecomposeGEPExpression(const Value *V, int64_t &BaseOffs,
SmallVectorImpl<VariableGEPIndex> &VarIndices,
- const TargetData *TD) {
+ const DataLayout *TD) {
// Limit recursion depth to limit compile time in crazy cases.
unsigned MaxLookup = 6;
@@ -277,7 +277,7 @@ DecomposeGEPExpression(const Value *V, int64_t &BaseOffs,
->getElementType()->isSized())
return V;
- // If we are lacking TargetData information, we can't compute the offets of
+ // If we are lacking DataLayout information, we can't compute the offets of
// elements computed by GEPs. However, we can handle bitcast equivalent
// GEPs.
if (TD == 0) {
@@ -868,7 +868,7 @@ BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size,
const Value *GEP1BasePtr =
DecomposeGEPExpression(GEP1, GEP1BaseOffset, GEP1VariableIndices, TD);
// DecomposeGEPExpression and GetUnderlyingObject should return the
- // same result except when DecomposeGEPExpression has no TargetData.
+ // same result except when DecomposeGEPExpression has no DataLayout.
if (GEP1BasePtr != UnderlyingV1 || GEP2BasePtr != UnderlyingV2) {
assert(TD == 0 &&
"DecomposeGEPExpression and GetUnderlyingObject disagree!");
@@ -902,7 +902,7 @@ BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size,
DecomposeGEPExpression(GEP2, GEP2BaseOffset, GEP2VariableIndices, TD);
// DecomposeGEPExpression and GetUnderlyingObject should return the
- // same result except when DecomposeGEPExpression has no TargetData.
+ // same result except when DecomposeGEPExpression has no DataLayout.
if (GEP1BasePtr != UnderlyingV1 || GEP2BasePtr != UnderlyingV2) {
assert(TD == 0 &&
"DecomposeGEPExpression and GetUnderlyingObject disagree!");
@@ -937,7 +937,7 @@ BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size,
DecomposeGEPExpression(GEP1, GEP1BaseOffset, GEP1VariableIndices, TD);
// DecomposeGEPExpression and GetUnderlyingObject should return the
- // same result except when DecomposeGEPExpression has no TargetData.
+ // same result except when DecomposeGEPExpression has no DataLayout.
if (GEP1BasePtr != UnderlyingV1) {
assert(TD == 0 &&
"DecomposeGEPExpression and GetUnderlyingObject disagree!");
diff --git a/lib/Analysis/CaptureTracking.cpp b/lib/Analysis/CaptureTracking.cpp
index 974b906b34..d9c02990a8 100644
--- a/lib/Analysis/CaptureTracking.cpp
+++ b/lib/Analysis/CaptureTracking.cpp
@@ -23,6 +23,8 @@ using namespace llvm;
CaptureTracker::~CaptureTracker() {}
+bool CaptureTracker::shouldExplore(Use *U) { return true; }
+
namespace {
struct SimpleCaptureTracker : public CaptureTracker {
explicit SimpleCaptureTracker(bool ReturnCaptures)
@@ -30,8 +32,6 @@ namespace {
void tooManyUses() { Captured = true; }
- bool shouldExplore(Use *U) { return true; }
-
bool captured(Use *U) {
if (isa<ReturnInst>(U->getUser()) && !ReturnCaptures)
return false;
diff --git a/lib/Analysis/CodeMetrics.cpp b/lib/Analysis/CodeMetrics.cpp
index 9a1ca63c1c..651a54be1b 100644
--- a/lib/Analysis/CodeMetrics.cpp
+++ b/lib/Analysis/CodeMetrics.cpp
@@ -15,7 +15,7 @@
#include "llvm/Function.h"
#include "llvm/Support/CallSite.h"
#include "llvm/IntrinsicInst.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
using namespace llvm;
@@ -54,7 +54,7 @@ bool llvm::callIsSmall(ImmutableCallSite CS) {
return false;
}
-bool llvm::isInstructionFree(const Instruction *I, const TargetData *TD) {
+bool llvm::isInstructionFree(const Instruction *I, const DataLayout *TD) {
if (isa<PHINode>(I))
return true;
@@ -119,7 +119,7 @@ bool llvm::isInstructionFree(const Instruction *I, const TargetData *TD) {
/// analyzeBasicBlock - Fill in the current structure with information gleaned
/// from the specified block.
void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB,
- const TargetData *TD) {
+ const DataLayout *TD) {
++NumBlocks;
unsigned NumInstsBeforeThisBB = NumInsts;
for (BasicBlock::const_iterator II = BB->begin(), E = BB->end();
@@ -189,14 +189,14 @@ void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB,
NumBBInsts[BB] = NumInsts - NumInstsBeforeThisBB;
}
-void CodeMetrics::analyzeFunction(Function *F, const TargetData *TD) {
+void CodeMetrics::analyzeFunction(Function *F, const DataLayout *TD) {
// If this function contains a call that "returns twice" (e.g., setjmp or
// _setjmp) and it isn't marked with "returns twice" itself, never inline it.
// This is a hack because we depend on the user marking their local variables
// as volatile if they are live across a setjmp call, and they probably
// won't do this in callers.
exposesReturnsTwice = F->callsFunctionThatReturnsTwice() &&
- !F->getFnAttributes().hasReturnsTwiceAttr();
+ !F->getFnAttributes().hasAttribute(Attributes::ReturnsTwice);
// Look at the size of the callee.
for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index 4ad613c66a..b7bf044a36 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -11,7 +11,7 @@
//
// Also, to supplement the basic VMCore ConstantExpr simplifications,
// this file defines some additional folding routines that can make use of
-// TargetData information. These functions cannot go in VMCore due to library
+// DataLayout information. These functions cannot go in VMCore due to library
// dependency issues.
//
//===----------------------------------------------------------------------===//
@@ -25,7 +25,7 @@
#include "llvm/Intrinsics.h"
#include "llvm/Operator.h"
#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
@@ -42,10 +42,10 @@ using namespace llvm;
//===----------------------------------------------------------------------===//
/// FoldBitCast - Constant fold bitcast, symbolically evaluating it with
-/// TargetData. This always returns a non-null constant, but it may be a
+/// DataLayout. This always returns a non-null constant, but it may be a
/// ConstantExpr if unfoldable.
static Constant *FoldBitCast(Constant *C, Type *DestTy,
- const TargetData &TD) {
+ const DataLayout &TD) {
// Catch the obvious splat cases.
if (C->isNullValue() && !DestTy->isX86_MMXTy())
return Constant::getNullValue(DestTy);
@@ -218,7 +218,7 @@ static Constant *FoldBitCast(Constant *C, Type *DestTy,
/// from a global, return the global and the constant. Because of
/// constantexprs, this function is recursive.
static bool IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV,
- int64_t &Offset, const TargetData &TD) {
+ int64_t &Offset, const DataLayout &TD) {
// Trivial case, constant is the global.
if ((GV = dyn_cast<GlobalValue>(C))) {
Offset = 0;
@@ -274,7 +274,7 @@ static bool IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV,
/// the CurPtr buffer. TD is the target data.
static bool ReadDataFromGlobal(Constant *C, uint64_t ByteOffset,
unsigned char *CurPtr, unsigned BytesLeft,
- const TargetData &TD) {
+ const DataLayout &TD) {
assert(ByteOffset <= TD.getTypeAllocSize(C->getType()) &&
"Out of range access");
@@ -388,7 +388,7 @@ static bool ReadDataFromGlobal(Constant *C, uint64_t ByteOffset,
}
static Constant *FoldReinterpretLoadFromConstPtr(Constant *C,
- const TargetData &TD) {
+ const DataLayout &TD) {
Type *LoadTy = cast<PointerType>(C->getType())->getElementType();
IntegerType *IntType = dyn_cast<IntegerType>(LoadTy);
@@ -455,7 +455,7 @@ static Constant *FoldReinterpretLoadFromConstPtr(Constant *C,
/// produce if it is constant and determinable. If this is not determinable,
/// return null.
Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C,
- const TargetData *TD) {
+ const DataLayout *TD) {
// First, try the easy cases:
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C))
if (GV->isConstant() && GV->hasDefinitiveInitializer())
@@ -529,7 +529,7 @@ Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C,
return 0;
}
-static Constant *ConstantFoldLoadInst(const LoadInst *LI, const TargetData *TD){
+static Constant *ConstantFoldLoadInst(const LoadInst *LI, const DataLayout *TD){
if (LI->isVolatile()) return 0;
if (Constant *C = dyn_cast<Constant>(LI->getOperand(0)))
@@ -543,7 +543,7 @@ static Constant *ConstantFoldLoadInst(const LoadInst *LI, const TargetData *TD){
/// these together. If target data info is available, it is provided as TD,
/// otherwise TD is null.
static Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0,
- Constant *Op1, const TargetData *TD){
+ Constant *Op1, const DataLayout *TD){
// SROA
// Fold (and 0xffffffff00000000, (shl x, 32)) -> shl.
@@ -572,7 +572,7 @@ static Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0,
/// explicitly cast them so that they aren't implicitly casted by the
/// getelementptr.
static Constant *CastGEPIndices(ArrayRef<Constant *> Ops,
- Type *ResultTy, const TargetData *TD,
+ Type *ResultTy, const DataLayout *TD,
const TargetLibraryInfo *TLI) {
if (!TD) return 0;
Type *IntPtrTy = TD->getIntPtrType(ResultTy->getContext());
@@ -622,7 +622,7 @@ static Constant* StripPtrCastKeepAS(Constant* Ptr) {
/// SymbolicallyEvaluateGEP - If we can symbolically evaluate the specified GEP
/// constant expression, do so.
static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops,
- Type *ResultTy, const TargetData *TD,
+ Type *ResultTy, const DataLayout *TD,
const TargetLibraryInfo *TLI) {
Constant *Ptr = Ops[0];
if (!TD || !cast<PointerType>(Ptr->getType())->getElementType()->isSized() ||
@@ -786,7 +786,7 @@ static Constant *SymbolicallyEvaluateGEP(ArrayRef<Constant *> Ops,
/// this function can only fail when attempting to fold instructions like loads
/// and stores, which have no constant expression form.
Constant *llvm::ConstantFoldInstruction(Instruction *I,
- const TargetData *TD,
+ const DataLayout *TD,
const TargetLibraryInfo *TLI) {
// Handle PHI nodes quickly here...
if (PHINode *PN = dyn_cast<PHINode>(I)) {
@@ -856,10 +856,10 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I,
}
/// ConstantFoldConstantExpression - Attempt to fold the constant expression
-/// using the specified TargetData. If successful, the constant result is
+/// using the specified DataLayout. If successful, the constant result is
/// result is returned, if not, null is returned.
Constant *llvm::ConstantFoldConstantExpression(const ConstantExpr *CE,
- const TargetData *TD,
+ const DataLayout *TD,
const TargetLibraryInfo *TLI) {
SmallVector<Constant*, 8> Ops;
for (User::const_op_iterator i = CE->op_begin(), e = CE->op_end();
@@ -889,7 +889,7 @@ Constant *llvm::ConstantFoldConstantExpression(const ConstantExpr *CE,
///
Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
ArrayRef<Constant *> Ops,
- const TargetData *TD,
+ const DataLayout *TD,
const TargetLibraryInfo *TLI) {
// Handle easy binops first.
if (Instruction::isBinaryOp(Opcode)) {
@@ -976,7 +976,7 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
///
Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate,
Constant *Ops0, Constant *Ops1,
- const TargetData *TD,
+ const DataLayout *TD,
const TargetLibraryInfo *TLI) {
// fold: icmp (inttoptr x), null -> icmp x, 0
// fold: icmp (ptrtoint x), 0 -> icmp x, null
diff --git a/lib/Analysis/IVUsers.cpp b/lib/Analysis/IVUsers.cpp
index 3807ccdbf8..d4221b89e0 100644
--- a/lib/Analysis/IVUsers.cpp
+++ b/lib/Analysis/IVUsers.cpp
@@ -22,7 +22,7 @@
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"
@@ -235,7 +235,7 @@ bool IVUsers::runOnLoop(Loop *l, LPPassManager &LPM) {
LI = &getAnalysis<LoopInfo>();
DT = &getAnalysis<DominatorTree>();
SE = &getAnalysis<ScalarEvolution>();
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
// Find all uses of induction variables in this loop, and categorize
// them by stride. Start by finding all of the PHI nodes in the header for
diff --git a/lib/Analysis/InlineCost.cpp b/lib/Analysis/InlineCost.cpp
index 7ecc06bbb2..5f51f775f1 100644
--- a/lib/Analysis/InlineCost.cpp
+++ b/lib/Analysis/InlineCost.cpp
@@ -24,7 +24,7 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/Operator.h"
#include "llvm/GlobalAlias.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
@@ -41,8 +41,8 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
typedef InstVisitor<CallAnalyzer, bool> Base;
friend class InstVisitor<CallAnalyzer, bool>;
- // TargetData if available, or null.
- const TargetData *const TD;
+ // DataLayout if available, or null.
+ const DataLayout *const TD;
// The called function.
Function &F;
@@ -126,9 +126,9 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
bool visitCallSite(CallSite CS);
public:
- CallAnalyzer(const TargetData *TD, Function &Callee, int Threshold)
+ CallAnalyzer(const DataLayout *TD, Function &Callee, int Threshold)
: TD(TD), F(Callee), Threshold(Threshold), Cost(0),
- AlwaysInline(F.getFnAttributes().hasAlwaysInlineAttr()),
+ AlwaysInline(F.getFnAttributes().hasAttribute(Attributes::AlwaysInline)),
IsCallerRecursive(false), IsRecursiveCall(false),
ExposesReturnsTwice(false), HasDynamicAlloca(false), AllocatedSize(0),
NumInstructions(0), NumVectorInstructions(0),
@@ -142,6 +142,7 @@ public:
int getThreshold() { return Threshold; }
int getCost() { return Cost; }
+ bool isAlwaysInline() { return AlwaysInline; }
// Keep a bunch of stats about the cost savings found so we can print them
// out when debugging.
@@ -613,7 +614,7 @@ bool CallAnalyzer::visitStore(StoreInst &I) {
bool CallAnalyzer::visitCallSite(CallSite CS) {
if (CS.isCall() && cast<CallInst>(CS.getInstruction())->canReturnTwice() &&
- !F.getFnAttributes().hasReturnsTwiceAttr()) {
+ !F.getFnAttributes().hasAttribute(Attributes::ReturnsTwice)) {
// This aborts the entire analysis.
ExposesReturnsTwice = true;
return false;
@@ -832,7 +833,7 @@ bool CallAnalyzer::analyzeCall(CallSite CS) {
// one load and one store per word copied.
// FIXME: The maxStoresPerMemcpy setting from the target should be used
// here instead of a magic number of 8, but it's not available via
- // TargetData.
+ // DataLayout.
NumStores = std::min(NumStores, 8U);
Cost -= 2 * NumStores * InlineConstants::InstrCost;
@@ -1043,7 +1044,8 @@ InlineCost InlineCostAnalyzer::getInlineCost(CallSite CS, Function *Callee,
// something else. Don't inline functions marked noinline or call sites
// marked noinline.
if (!Callee || Callee->mayBeOverridden() ||
- Callee->getFnAttributes().hasNoInlineAttr() || CS.isNoInline())
+ Callee->getFnAttributes().hasAttribute(Attributes::NoInline) ||
+ CS.isNoInline())
return llvm::InlineCost::getNever();
DEBUG(llvm::dbgs() << " Analyzing call of " << Callee->getName()
@@ -1057,7 +1059,8 @@ InlineCost InlineCostAnalyzer::getInlineCost(CallSite CS, Function *Callee,
// Check if there was a reason to force inlining or no inlining.
if (!ShouldInline && CA.getCost() < CA.getThreshold())
return InlineCost::getNever();
- if (ShouldInline && CA.getCost() >= CA.getThreshold())
+ if (ShouldInline && (CA.isAlwaysInline() ||
+ CA.getCost() >= CA.getThreshold()))
return InlineCost::getAlways();
return llvm::InlineCost::get(CA.getCost(), CA.getThreshold());
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp
index 379a35ad37..b3d62487fc 100644
--- a/lib/Analysis/InstructionSimplify.cpp
+++ b/lib/Analysis/InstructionSimplify.cpp
@@ -31,7 +31,7 @@
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/PatternMatch.h"
#include "llvm/Support/ValueHandle.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
using namespace llvm;
using namespace llvm::PatternMatch;
@@ -42,11 +42,11 @@ STATISTIC(NumFactor , "Number of factorizations");
STATISTIC(NumReassoc, "Number of reassociations");
struct Query {
- const TargetData *TD;
+ const DataLayout *TD;
const TargetLibraryInfo *TLI;
const DominatorTree *DT;
- Query(const TargetData *td, const TargetLibraryInfo *tli,
+ Query(const DataLayout *td, const TargetLibraryInfo *tli,
const DominatorTree *dt) : TD(td), TLI(tli), DT(dt) {}
};
@@ -651,7 +651,7 @@ static Value *SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
}
Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
- const TargetData *TD, const TargetLibraryInfo *TLI,
+ const DataLayout *TD, const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyAddInst(Op0, Op1, isNSW, isNUW, Query (TD, TLI, DT),
RecursionLimit);
@@ -664,7 +664,7 @@ Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
/// if the GEP has all-constant indices. Returns false if any non-constant
/// index is encountered leaving the 'Offset' in an undefined state. The
/// 'Offset' APInt must be the bitwidth of the target's pointer size.
-static bool accumulateGEPOffset(const TargetData &TD, GEPOperator *GEP,
+static bool accumulateGEPOffset(const DataLayout &TD, GEPOperator *GEP,
APInt &Offset) {
unsigned IntPtrWidth = TD.getPointerSizeInBits();
assert(IntPtrWidth == Offset.getBitWidth());
@@ -696,7 +696,7 @@ static bool accumulateGEPOffset(const TargetData &TD, GEPOperator *GEP,
/// accumulates the total constant offset applied in the returned constant. It
/// returns 0 if V is not a pointer, and returns the constant '0' if there are
/// no constant offsets applied.
-static Constant *stripAndComputeConstantOffsets(const TargetData &TD,
+static Constant *stripAndComputeConstantOffsets(const DataLayout &TD,
Value *&V) {
if (!V->getType()->isPointerTy())
return 0;
@@ -731,7 +731,7 @@ static Constant *stripAndComputeConstantOffsets(const TargetData &TD,
/// \brief Compute the constant difference between two pointer values.
/// If the difference is not a constant, returns zero.
-static Constant *computePointerDifference(const TargetData &TD,
+static Constant *computePointerDifference(const DataLayout &TD,
Value *LHS, Value *RHS) {
Constant *LHSOffset = stripAndComputeConstantOffsets(TD, LHS);
if (!LHSOffset)
@@ -880,7 +880,7 @@ static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
}
Value *llvm::SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
- const TargetData *TD, const TargetLibraryInfo *TLI,
+ const DataLayout *TD, const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifySubInst(Op0, Op1, isNSW, isNUW, Query (TD, TLI, DT),
RecursionLimit);
@@ -951,7 +951,7 @@ static Value *SimplifyMulInst(Value *Op0, Value *Op1, const Query &Q,
return 0;
}
-Value *llvm::SimplifyMulInst(Value *Op0, Value *Op1, const TargetData *TD,
+Value *llvm::SimplifyMulInst(Value *Op0, Value *Op1, const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyMulInst(Op0, Op1, Query (TD, TLI, DT), RecursionLimit);
@@ -1039,7 +1039,7 @@ static Value *SimplifySDivInst(Value *Op0, Value *Op1, const Query &Q,
return 0;
}
-Value *llvm::SimplifySDivInst(Value *Op0, Value *Op1, const TargetData *TD,
+Value *llvm::SimplifySDivInst(Value *Op0, Value *Op1, const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifySDivInst(Op0, Op1, Query (TD, TLI, DT), RecursionLimit);
@@ -1055,7 +1055,7 @@ static Value *SimplifyUDivInst(Value *Op0, Value *Op1, const Query &Q,
return 0;
}
-Value *llvm::SimplifyUDivInst(Value *Op0, Value *Op1, const TargetData *TD,
+Value *llvm::SimplifyUDivInst(Value *Op0, Value *Op1, const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyUDivInst(Op0, Op1, Query (TD, TLI, DT), RecursionLimit);
@@ -1074,7 +1074,7 @@ static Value *SimplifyFDivInst(Value *Op0, Value *Op1, const Query &Q,
return 0;
}
-Value *llvm::SimplifyFDivInst(Value *Op0, Value *Op1, const TargetData *TD,
+Value *llvm::SimplifyFDivInst(Value *Op0, Value *Op1, const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyFDivInst(Op0, Op1, Query (TD, TLI, DT), RecursionLimit);
@@ -1144,7 +1144,7 @@ static Value *SimplifySRemInst(Value *Op0, Value *Op1, const Query &Q,
return 0;
}
-Value *llvm::SimplifySRemInst(Value *Op0, Value *Op1, const TargetData *TD,
+Value *llvm::SimplifySRemInst(Value *Op0, Value *Op1, const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifySRemInst(Op0, Op1, Query (TD, TLI, DT), RecursionLimit);
@@ -1160,7 +1160,7 @@ static Value *SimplifyURemInst(Value *Op0, Value *Op1, const Query &Q,
return 0;
}
-Value *llvm::SimplifyURemInst(Value *Op0, Value *Op1, const TargetData *TD,
+Value *llvm::SimplifyURemInst(Value *Op0, Value *Op1, const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyURemInst(Op0, Op1, Query (TD, TLI, DT), RecursionLimit);
@@ -1179,7 +1179,7 @@ static Value *SimplifyFRemInst(Value *Op0, Value *Op1, const Query &,
return 0;
}
-Value *llvm::SimplifyFRemInst(Value *Op0, Value *Op1, const TargetData *TD,
+Value *llvm::SimplifyFRemInst(Value *Op0, Value *Op1, const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyFRemInst(Op0, Op1, Query (TD, TLI, DT), RecursionLimit);
@@ -1248,7 +1248,7 @@ static Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
}
Value *llvm::SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
- const TargetData *TD, const TargetLibraryInfo *TLI,
+ const DataLayout *TD, const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyShlInst(Op0, Op1, isNSW, isNUW, Query (TD, TLI, DT),
RecursionLimit);
@@ -1275,7 +1275,7 @@ static Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
}
Value *llvm::SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
- const TargetData *TD,
+ const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyLShrInst(Op0, Op1, isExact, Query (TD, TLI, DT),
@@ -1307,7 +1307,7 @@ static Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
}
Value *llvm::SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
- const TargetData *TD,
+ const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyAShrInst(Op0, Op1, isExact, Query (TD, TLI, DT),
@@ -1407,7 +1407,7 @@ static Value *SimplifyAndInst(Value *Op0, Value *Op1, const Query &Q,
return 0;
}
-Value *llvm::SimplifyAndInst(Value *Op0, Value *Op1, const TargetData *TD,
+Value *llvm::SimplifyAndInst(Value *Op0, Value *Op1, const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyAndInst(Op0, Op1, Query (TD, TLI, DT), RecursionLimit);
@@ -1501,7 +1501,7 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const Query &Q,
return 0;
}
-Value *llvm::SimplifyOrInst(Value *Op0, Value *Op1, const TargetData *TD,
+Value *llvm::SimplifyOrInst(Value *Op0, Value *Op1, const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyOrInst(Op0, Op1, Query (TD, TLI, DT), RecursionLimit);
@@ -1561,7 +1561,7 @@ static Value *SimplifyXorInst(Value *Op0, Value *Op1, const Query &Q,
return 0;
}
-Value *llvm::SimplifyXorInst(Value *Op0, Value *Op1, const TargetData *TD,
+Value *llvm::SimplifyXorInst(Value *Op0, Value *Op1, const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyXorInst(Op0, Op1, Query (TD, TLI, DT), RecursionLimit);
@@ -1591,7 +1591,7 @@ static Value *ExtractEquivalentCondition(Value *V, CmpInst::Predicate Pred,
return 0;
}
-static Constant *computePointerICmp(const TargetData &TD,
+static Constant *computePointerICmp(const DataLayout &TD,
CmpInst::Predicate Pred,
Value *LHS, Value *RHS) {
// We can only fold certain predicates on pointer comparisons.
@@ -2399,7 +2399,7 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
}
Value *llvm::SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const TargetData *TD,
+ const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyICmpInst(Predicate, LHS, RHS, Query (TD, TLI, DT),
@@ -2496,7 +2496,7 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
}
Value *llvm::SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const TargetData *TD,
+ const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyFCmpInst(Predicate, LHS, RHS, Query (TD, TLI, DT),
@@ -2531,7 +2531,7 @@ static Value *SimplifySelectInst(Value *CondVal, Value *TrueVal,
}
Value *llvm::SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
- const TargetData *TD,
+ const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifySelectInst(Cond, TrueVal, FalseVal, Query (TD, TLI, DT),
@@ -2579,7 +2579,7 @@ static Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const Query &Q, unsigned) {
return ConstantExpr::getGetElementPtr(cast<Constant>(Ops[0]), Ops.slice(1));
}
-Value *llvm::SimplifyGEPInst(ArrayRef<Value *> Ops, const TargetData *TD,
+Value *llvm::SimplifyGEPInst(ArrayRef<Value *> Ops, const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyGEPInst(Ops, Query (TD, TLI, DT), RecursionLimit);
@@ -2616,7 +2616,7 @@ static Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
Value *llvm::SimplifyInsertValueInst(Value *Agg, Value *Val,
ArrayRef<unsigned> Idxs,
- const TargetData *TD,
+ const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyInsertValueInst(Agg, Val, Idxs, Query (TD, TLI, DT),
@@ -2664,7 +2664,7 @@ static Value *SimplifyTruncInst(Value *Op, Type *Ty, const Query &Q, unsigned) {
return 0;
}
-Value *llvm::SimplifyTruncInst(Value *Op, Type *Ty, const TargetData *TD,
+Value *llvm::SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyTruncInst(Op, Ty, Query (TD, TLI, DT), RecursionLimit);
@@ -2730,7 +2730,7 @@ static Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
}
Value *llvm::SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
- const TargetData *TD, const TargetLibraryInfo *TLI,
+ const DataLayout *TD, const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyBinOp(Opcode, LHS, RHS, Query (TD, TLI, DT), RecursionLimit);
}
@@ -2745,7 +2745,7 @@ static Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
}
Value *llvm::SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const TargetData *TD, const TargetLibraryInfo *TLI,
+ const DataLayout *TD, const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return ::SimplifyCmpInst(Predicate, LHS, RHS, Query (TD, TLI, DT),
RecursionLimit);
@@ -2761,7 +2761,7 @@ static Value *SimplifyCallInst(CallInst *CI, const Query &) {
/// SimplifyInstruction - See if we can compute a simplified version of this
/// instruction. If not, this returns null.
-Value *llvm::SimplifyInstruction(Instruction *I, const TargetData *TD,
+Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
Value *Result;
@@ -2881,7 +2881,7 @@ Value *llvm::SimplifyInstruction(Instruction *I, const TargetData *TD,
/// This routine returns 'true' only when *it* simplifies something. The passed
/// in simplified value does not count toward this.
static bool replaceAndRecursivelySimplifyImpl(Instruction *I, Value *SimpleV,
- const TargetData *TD,
+ const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
bool Simplified = false;
@@ -2936,14 +2936,14 @@ static bool replaceAndRecursivelySimplifyImpl(Instruction *I, Value *SimpleV,
}
bool llvm::recursivelySimplifyInstruction(Instruction *I,
- const TargetData *TD,
+ const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
return replaceAndRecursivelySimplifyImpl(I, 0, TD, TLI, DT);
}
bool llvm::replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV,
- const TargetData *TD,
+ const DataLayout *TD,
const TargetLibraryInfo *TLI,
const DominatorTree *DT) {
assert(I != SimpleV && "replaceAndRecursivelySimplify(X,X) is not valid!");
diff --git a/lib/Analysis/LazyValueInfo.cpp b/lib/Analysis/LazyValueInfo.cpp
index ec618fad22..751118a86e 100644
--- a/lib/Analysis/LazyValueInfo.cpp
+++ b/lib/Analysis/LazyValueInfo.cpp
@@ -19,7 +19,7 @@
#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Analysis/ConstantFolding.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/ConstantRange.h"
@@ -212,7 +212,7 @@ public:
// Unless we can prove that the two Constants are different, we must
// move to overdefined.
- // FIXME: use TargetData/TargetLibraryInfo for smarter constant folding.
+ // FIXME: use DataLayout/TargetLibraryInfo for smarter constant folding.
if (ConstantInt *Res = dyn_cast<ConstantInt>(
ConstantFoldCompareInstOperands(CmpInst::ICMP_NE,
getConstant(),
@@ -238,7 +238,7 @@ public:
// Unless we can prove that the two Constants are different, we must
// move to overdefined.
- // FIXME: use TargetData/TargetLibraryInfo for smarter constant folding.
+ // FIXME: use DataLayout/TargetLibraryInfo for smarter constant folding.
if (ConstantInt *Res = dyn_cast<ConstantInt>(
ConstantFoldCompareInstOperands(CmpInst::ICMP_NE,
getNotConstant(),
@@ -1009,7 +1009,7 @@ bool LazyValueInfo::runOnFunction(Function &F) {
if (PImpl)
getCache(PImpl).clear();
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
TLI = &getAnalysis<TargetLibraryInfo>();
// Fully lazy.
diff --git a/lib/Analysis/Lint.cpp b/lib/Analysis/Lint.cpp
index 7bd945733b..6d6d580ed1 100644
--- a/lib/Analysis/Lint.cpp
+++ b/lib/Analysis/Lint.cpp
@@ -43,7 +43,7 @@
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Assembly/Writer.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
@@ -103,7 +103,7 @@ namespace {
Module *Mod;
AliasAnalysis *AA;
DominatorTree *DT;
- TargetData *TD;
+ DataLayout *TD;
TargetLibraryInfo *TLI;
std::string Messages;
@@ -177,7 +177,7 @@ bool Lint::runOnFunction(Function &F) {
Mod = F.getParent();
AA = &getAnalysis<AliasAnalysis>();
DT = &getAnalysis<DominatorTree>();
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
TLI = &getAnalysis<TargetLibraryInfo>();
visit(F);
dbgs() << MessagesStr.str();
@@ -506,7 +506,7 @@ void Lint::visitShl(BinaryOperator &I) {
"Undefined result: Shift count out of range", &I);
}
-static bool isZero(Value *V, TargetData *TD) {
+static bool isZero(Value *V, DataLayout *TD) {
// Assume undef could be zero.
if (isa<UndefValue>(V)) return true;
diff --git a/lib/Analysis/Loads.cpp b/lib/Analysis/Loads.cpp
index 873a27543d..73aa8b49cd 100644
--- a/lib/Analysis/Loads.cpp
+++ b/lib/Analysis/Loads.cpp
@@ -13,7 +13,7 @@
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/GlobalAlias.h"
#include "llvm/GlobalVariable.h"
#include "llvm/IntrinsicInst.h"
@@ -52,8 +52,8 @@ static bool AreEquivalentAddressValues(const Value *A, const Value *B) {
/// bitcasts to get back to the underlying object being addressed, keeping
/// track of the offset in bytes from the GEPs relative to the result.
/// This is closely related to GetUnderlyingObject but is located
-/// here to avoid making VMCore depend on TargetData.
-static Value *getUnderlyingObjectWithOffset(Value *V, const TargetData *TD,
+/// here to avoid making VMCore depend on DataLayout.
+static Value *getUnderlyingObjectWithOffset(Value *V, const DataLayout *TD,
uint64_t &ByteOffset,
unsigned MaxLookup = 6) {
if (!V->getType()->isPointerTy())
@@ -85,7 +85,7 @@ static Value *getUnderlyingObjectWithOffset(Value *V, const TargetData *TD,
/// specified pointer, we do a quick local scan of the basic block containing
/// ScanFrom, to determine if the address is already accessed.
bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom,
- unsigned Align, const TargetData *TD) {
+ unsigned Align, const DataLayout *TD) {
uint64_t ByteOffset = 0;
Value *Base = V;
if (TD)
diff --git a/lib/Analysis/LoopDependenceAnalysis.cpp b/lib/Analysis/LoopDependenceAnalysis.cpp
index 463269d9d9..b696e5fae1 100644
--- a/lib/Analysis/LoopDependenceAnalysis.cpp
+++ b/lib/Analysis/LoopDependenceAnalysis.cpp
@@ -35,7 +35,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
using namespace llvm;
STATISTIC(NumAnswered, "Number of dependence queries answered");
diff --git a/lib/Analysis/MemoryBuiltins.cpp b/lib/Analysis/MemoryBuiltins.cpp
index 5b2313e3a6..0a539fe758 100644
--- a/lib/Analysis/MemoryBuiltins.cpp
+++ b/lib/Analysis/MemoryBuiltins.cpp
@@ -25,7 +25,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/Utils/Local.h"
using namespace llvm;
@@ -132,7 +132,7 @@ static const AllocFnsTy *getAllocationData(const Value *V, AllocType AllocTy,
static bool hasNoAliasAttr(const Value *V, bool LookThroughBitCast) {
ImmutableCallSite CS(LookThroughBitCast ? V->stripPointerCasts() : V);
- return CS && CS.hasFnAttr(Attribute::NoAlias);
+ return CS && CS.hasFnAttr(Attributes::NoAlias);
}
@@ -190,7 +190,7 @@ const CallInst *llvm::extractMallocCall(const Value *I,
return isMallocLikeFn(I, TLI) ? dyn_cast<CallInst>(I) : 0;
}
-static Value *computeArraySize(const CallInst *CI, const TargetData *TD,
+static Value *computeArraySize(const CallInst *CI, const DataLayout *TD,
const TargetLibraryInfo *TLI,
bool LookThroughSExt = false) {
if (!CI)
@@ -220,7 +220,7 @@ static Value *computeArraySize(const CallInst *CI, const TargetData *TD,
/// is a call to malloc whose array size can be determined and the array size
/// is not constant 1. Otherwise, return NULL.
const CallInst *llvm::isArrayMalloc(const Value *I,
- const TargetData *TD,
+ const DataLayout *TD,
const TargetLibraryInfo *TLI) {
const CallInst *CI = extractMallocCall(I, TLI);
Value *ArraySize = computeArraySize(CI, TD, TLI);
@@ -281,7 +281,7 @@ Type *llvm::getMallocAllocatedType(const CallInst *CI,
/// then return that multiple. For non-array mallocs, the multiple is
/// constant 1. Otherwise, return NULL for mallocs whose array size cannot be
/// determined.
-Value *llvm::getMallocArraySize(CallInst *CI, const TargetData *TD,
+Value *llvm::getMallocArraySize(CallInst *CI, const DataLayout *TD,
const TargetLibraryInfo *TLI,
bool LookThroughSExt) {
assert(isMallocLikeFn(CI, TLI) && "getMallocArraySize and not malloc call");
@@ -341,7 +341,7 @@ const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) {
/// object size in Size if successful, and false otherwise.
/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
/// byval arguments, and global variables.
-bool llvm::getObjectSize(const Value *Ptr, uint64_t &Size, const TargetData *TD,
+bool llvm::getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD,
const TargetLibraryInfo *TLI, bool RoundToAlign) {
if (!TD)
return false;
@@ -373,7 +373,7 @@ APInt ObjectSizeOffsetVisitor::align(APInt Size, uint64_t Align) {
return Size;
}
-ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor(const TargetData *TD,
+ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor(const DataLayout *TD,
const TargetLibraryInfo *TLI,
LLVMContext &Context,
bool RoundToAlign)
@@ -559,7 +559,7 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitInstruction(Instruction &I) {
}
-ObjectSizeOffsetEvaluator::ObjectSizeOffsetEvaluator(const TargetData *TD,
+ObjectSizeOffsetEvaluator::ObjectSizeOffsetEvaluator(const DataLayout *TD,
const TargetLibraryInfo *TLI,
LLVMContext &Context)
: TD(TD), TLI(TLI), Context(Context), Builder(Context, TargetFolder(TD)) {
diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp
index 9ce9f8c801..9316df6fbf 100644
--- a/lib/Analysis/MemoryDependenceAnalysis.cpp
+++ b/lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -30,7 +30,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/PredIteratorCache.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
using namespace llvm;
STATISTIC(NumCacheNonLocal, "Number of fully cached non-local responses");
@@ -89,7 +89,7 @@ void MemoryDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
bool MemoryDependenceAnalysis::runOnFunction(Function &) {
AA = &getAnalysis<AliasAnalysis>();
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
DT = getAnalysisIfAvailable<DominatorTree>();
if (PredCache == 0)
PredCache.reset(new PredIteratorCache());
@@ -256,7 +256,7 @@ isLoadLoadClobberIfExtendedToFullWidth(const AliasAnalysis::Location &MemLoc,
const Value *&MemLocBase,
int64_t &MemLocOffs,
const LoadInst *LI,
- const TargetData *TD) {
+ const DataLayout *TD) {
// If we have no target data, we can't do this.
if (TD == 0) return false;
@@ -280,7 +280,7 @@ isLoadLoadClobberIfExtendedToFullWidth(const AliasAnalysis::Location &MemLoc,
unsigned MemoryDependenceAnalysis::
getLoadLoadClobberFullWidthSize(const Value *MemLocBase, int64_t MemLocOffs,
unsigned MemLocSize, const LoadInst *LI,
- const TargetData &TD) {
+ const DataLayout &TD) {
// We can only extend simple integer loads.
if (!isa<IntegerType>(LI->getType()) || !LI->isSimple()) return 0;
@@ -327,12 +327,12 @@ getLoadLoadClobberFullWidthSize(const Value *MemLocBase, int64_t MemLocOffs,
return 0;
if (LIOffs+NewLoadByteSize > MemLocEnd &&
- LI->getParent()->getParent()->getFnAttributes().hasAddressSafetyAttr()){
+ LI->getParent()->getParent()->getFnAttributes().
+ hasAttribute(Attributes::AddressSafety))
// We will be reading past the location accessed by the original program.
// While this is safe in a regular build, Address Safety analysis tools
// may start reporting false warnings. So, don't do widening.
return 0;
- }
// If a load of this width would include all of MemLoc, then we succeed.
if (LIOffs+NewLoadByteSize >= MemLocEnd)
diff --git a/lib/Analysis/NoAliasAnalysis.cpp b/lib/Analysis/NoAliasAnalysis.cpp
index 101c2d5b02..2eb4137c53 100644
--- a/lib/Analysis/NoAliasAnalysis.cpp
+++ b/lib/Analysis/NoAliasAnalysis.cpp
@@ -15,7 +15,7 @@
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Pass.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
using namespace llvm;
namespace {
@@ -36,7 +36,7 @@ namespace {
virtual void initializePass() {
// Note: NoAA does not call InitializeAliasAnalysis because it's
// special and does not support chaining.
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
}
virtual AliasResult alias(const Location &LocA, const Location &LocB) {
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index 9b9c889496..5400646be1 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -73,7 +73,7 @@
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Assembly/Writer.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ConstantRange.h"
@@ -2582,7 +2582,7 @@ const SCEV *ScalarEvolution::getUMinExpr(const SCEV *LHS,
}
const SCEV *ScalarEvolution::getSizeOfExpr(Type *AllocTy) {
- // If we have TargetData, we can bypass creating a target-independent
+ // If we have DataLayout, we can bypass creating a target-independent
// constant expression and then folding it back into a ConstantInt.
// This is just a compile-time optimization.
if (TD)
@@ -2608,7 +2608,7 @@ const SCEV *ScalarEvolution::getAlignOfExpr(Type *AllocTy) {
const SCEV *ScalarEvolution::getOffsetOfExpr(StructType *STy,
unsigned FieldNo) {
- // If we have TargetData, we can bypass creating a target-independent
+ // If we have DataLayout, we can bypass creating a target-independent
// constant expression and then folding it back into a ConstantInt.
// This is just a compile-time optimization.
if (TD)
@@ -2673,7 +2673,7 @@ bool ScalarEvolution::isSCEVable(Type *Ty) const {
uint64_t ScalarEvolution::getTypeSizeInBits(Type *Ty) const {
assert(isSCEVable(Ty) && "Type is not SCEVable!");
- // If we have a TargetData, use it!
+ // If we have a DataLayout, use it!
if (TD)
return TD->getTypeSizeInBits(Ty);
@@ -2681,7 +2681,7 @@ uint64_t ScalarEvolution::getTypeSizeInBits(Type *Ty) const {
if (Ty->isIntegerTy())
return Ty->getPrimitiveSizeInBits();
- // The only other support type is pointer. Without TargetData, conservatively
+ // The only other support type is pointer. Without DataLayout, conservatively
// assume pointers are 64-bit.
assert(Ty->isPointerTy() && "isSCEVable permitted a non-SCEVable type!");
return 64;
@@ -2701,7 +2701,7 @@ Type *ScalarEvolution::getEffectiveSCEVType(Type *Ty) const {
assert(Ty->isPointerTy() && "Unexpected non-pointer non-integer type!");
if (TD) return TD->getIntPtrType(getContext());
- // Without TargetData, conservatively assume pointers are 64-bit.
+ // Without DataLayout, conservatively assume pointers are 64-bit.
return Type::getInt64Ty(getContext());
}
@@ -4751,7 +4751,7 @@ static PHINode *getConstantEvolvingPHI(Value *V, const Loop *L) {
/// reason, return null.
static Constant *EvaluateExpression(Value *V, const Loop *L,
DenseMap<Instruction *, Constant *> &Vals,
- const TargetData *TD,
+ const DataLayout *TD,
const TargetLibraryInfo *TLI) {
// Convenient constant check, but redundant for recursive calls.
if (Constant *C = dyn_cast<Constant>(V)) return C;
@@ -6590,7 +6590,7 @@ ScalarEvolution::ScalarEvolution()
bool ScalarEvolution::runOnFunction(Function &F) {
this->F = &F;
LI = &getAnalysis<LoopInfo>();
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
TLI = &getAnalysis<TargetLibraryInfo>();
DT = &getAnalysis<DominatorTree>();
return false;
diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp
index 62710c5e8b..5e05f4c8ca 100644
--- a/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -18,7 +18,7 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/LLVMContext.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/ADT/STLExtras.h"
@@ -212,7 +212,7 @@ static bool FactorOutConstant(const SCEV *&S,
const SCEV *&Remainder,
const SCEV *Factor,
ScalarEvolution &SE,
- const TargetData *TD) {
+ const DataLayout *TD) {
// Everything is divisible by one.
if (Factor->isOne())
return true;
@@ -253,7 +253,7 @@ static bool FactorOutConstant(const SCEV *&S,
// of the given factor.
if (const SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(S)) {
if (TD) {
- // With TargetData, the size is known. Check if there is a constant
+ // With DataLayout, the size is known. Check if there is a constant
// operand which is a multiple of the given factor. If so, we can
// factor it.
const SCEVConstant *FC = cast<SCEVConstant>(Factor);
@@ -267,7 +267,7 @@ static bool FactorOutConstant(const SCEV *&S,
return true;
}
} else {
- // Without TargetData, check if Factor can be factored out of any of the
+ // Without DataLayout, check if Factor can be factored out of any of the
// Mul's operands. If so, we can just remove it.
for (unsigned i = 0, e = M->getNumOperands(); i != e; ++i) {
const SCEV *SOp = M->getOperand(i);
@@ -458,7 +458,7 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
// An empty struct has no fields.
if (STy->getNumElements() == 0) break;
if (SE.TD) {
- // With TargetData, field offsets are known. See if a constant offset
+ // With DataLayout, field offsets are known. See if a constant offset
// falls within any of the struct fields.
if (Ops.empty()) break;
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(Ops[0]))
@@ -477,7 +477,7 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
}
}
} else {
- // Without TargetData, just check for an offsetof expression of the
+ // Without DataLayout, just check for an offsetof expression of the
// appropriate struct type.
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(Ops[i])) {
diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp
index 491224a4b6..951b442b87 100644
--- a/lib/Analysis/ValueTracking.cpp
+++ b/lib/Analysis/ValueTracking.cpp
@@ -22,7 +22,7 @@
#include "llvm/LLVMContext.h"
#include "llvm/Metadata.h"
#include "llvm/Operator.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Support/ConstantRange.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/MathExtras.h"
@@ -36,7 +36,7 @@ const unsigned MaxDepth = 6;
/// getBitWidth - Returns the bitwidth of the given scalar or pointer type (if
/// unknown returns 0). For vector types, returns the element type's bitwidth.
-static unsigned getBitWidth(Type *Ty, const TargetData *TD) {
+static unsigned getBitWidth(Type *Ty, const DataLayout *TD) {
if (unsigned BitWidth = Ty->getScalarSizeInBits())
return BitWidth;
assert(isa<PointerType>(Ty) && "Expected a pointer type!");
@@ -46,7 +46,7 @@ static unsigned getBitWidth(Type *Ty, const TargetData *TD) {
static void ComputeMaskedBitsAddSub(bool Add, Value *Op0, Value *Op1, bool NSW,
APInt &KnownZero, APInt &KnownOne,
APInt &KnownZero2, APInt &KnownOne2,
- const TargetData *TD, unsigned Depth) {
+ const DataLayout *TD, unsigned Depth) {
if (!Add) {
if (ConstantInt *CLHS = dyn_cast<ConstantInt>(Op0)) {
// We know that the top bits of C-X are clear if X contains less bits
@@ -132,7 +132,7 @@ static void ComputeMaskedBitsAddSub(bool Add, Value *Op0, Value *Op1, bool NSW,
static void ComputeMaskedBitsMul(Value *Op0, Value *Op1, bool NSW,
APInt &KnownZero, APInt &KnownOne,
APInt &KnownZero2, APInt &KnownOne2,
- const TargetData *TD, unsigned Depth) {
+ const DataLayout *TD, unsigned Depth) {
unsigned BitWidth = KnownZero.getBitWidth();
ComputeMaskedBits(Op1, KnownZero, KnownOne, TD, Depth+1);
ComputeMaskedBits(Op0, KnownZero2, KnownOne2, TD, Depth+1);
@@ -226,7 +226,7 @@ void llvm::computeMaskedBitsLoad(const MDNode &Ranges, APInt &KnownZero) {
/// same width as the vector element, and the bit is set only if it is true
/// for all of the elements in the vector.
void llvm::ComputeMaskedBits(Value *V, APInt &KnownZero, APInt &KnownOne,
- const TargetData *TD, unsigned Depth) {
+ const DataLayout *TD, unsigned Depth) {
assert(V && "No Value?");
assert(Depth <= MaxDepth && "Limit Search Depth");
unsigned BitWidth = KnownZero.getBitWidth();
@@ -308,11 +308,20 @@ void llvm::ComputeMaskedBits(Value *V, APInt &KnownZero, APInt &KnownOne,
}
if (Argument *A = dyn_cast<Argument>(V)) {
- // Get alignment information off byval arguments if specified in the IR.
- if (A->hasByValAttr())
- if (unsigned Align = A->getParamAlignment())
- KnownZero = APInt::getLowBitsSet(BitWidth,
- CountTrailingZeros_32(Align));
+ unsigned Align = 0;
+
+ if (A->hasByValAttr()) {
+ // Get alignment information off byval arguments if specified in the IR.
+ Align = A->getParamAlignment();
+ } else if (TD && A->hasStructRetAttr()) {
+ // An sret parameter has at least the ABI alignment of the return type.
+ Type *EltTy = cast<PointerType>(A->getType())->getElementType();
+ if (EltTy->isSized())
+ Align = TD->getABITypeAlignment(EltTy);
+ }
+
+ if (Align)
+ KnownZero = APInt::getLowBitsSet(BitWidth, CountTrailingZeros_32(Align));
return;
}
@@ -778,7 +787,7 @@ void llvm::ComputeMaskedBits(Value *V, APInt &KnownZero, APInt &KnownOne,
/// ComputeSignBit - Determine whether the sign bit is known to be zero or
/// one. Convenience wrapper around ComputeMaskedBits.
void llvm::ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne,
- const TargetData *TD, unsigned Depth) {
+ const DataLayout *TD, unsigned Depth) {
unsigned BitWidth = getBitWidth(V->getType(), TD);
if (!BitWidth) {
KnownZero = false;
@@ -796,7 +805,7 @@ void llvm::ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne,
/// bit set when defined. For vectors return true if every element is known to
/// be a power of two when defined. Supports values with integer or pointer
/// types and vectors of integers.
-bool llvm::isPowerOfTwo(Value *V, const TargetData *TD, bool OrZero,
+bool llvm::isPowerOfTwo(Value *V, const DataLayout *TD, bool OrZero,
unsigned Depth) {
if (Constant *C = dyn_cast<Constant>(V)) {
if (C->isNullValue())
@@ -859,7 +868,7 @@ bool llvm::isPowerOfTwo(Value *V, const TargetData *TD, bool OrZero,
/// when defined. For vectors return true if every element is known to be
/// non-zero when defined. Supports values with integer or pointer type and
/// vectors of integers.
-bool llvm::isKnownNonZero(Value *V, const TargetData *TD, unsigned Depth) {
+bool llvm::isKnownNonZero(Value *V, const DataLayout *TD, unsigned Depth) {
if (Constant *C = dyn_cast<Constant>(V)) {
if (C->isNullValue())
return false;
@@ -986,7 +995,7 @@ bool llvm::isKnownNonZero(Value *V, const TargetData *TD, unsigned Depth) {
/// same width as the vector element, and the bit is set only if it is true
/// for all of the elements in the vector.
bool llvm::MaskedValueIsZero(Value *V, const APInt &Mask,
- const TargetData *TD, unsigned Depth) {
+ const DataLayout *TD, unsigned Depth) {
APInt KnownZero(Mask.getBitWidth(), 0), KnownOne(Mask.getBitWidth(), 0);
ComputeMaskedBits(V, KnownZero, KnownOne, TD, Depth);
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
@@ -1003,10 +1012,10 @@ bool llvm::MaskedValueIsZero(Value *V, const APInt &Mask,
///
/// 'Op' must have a scalar integer type.
///
-unsigned llvm::ComputeNumSignBits(Value *V, const TargetData *TD,
+unsigned llvm::ComputeNumSignBits(Value *V, const DataLayout *TD,
unsigned Depth) {
assert((TD || V->getType()->isIntOrIntVectorTy()) &&
- "ComputeNumSignBits requires a TargetData object to operate "
+ "ComputeNumSignBits requires a DataLayout object to operate "
"on non-integer values!");
Type *Ty = V->getType();
unsigned TyBits = TD ? TD->getTypeSizeInBits(V->getType()->getScalarType()) :
@@ -1582,7 +1591,7 @@ Value *llvm::FindInsertedValue(Value *V, ArrayRef<unsigned> idx_range,
/// it can be expressed as a base pointer plus a constant offset. Return the
/// base and offset to the caller.
Value *llvm::GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset,
- const TargetData &TD) {
+ const DataLayout &TD) {
Operator *PtrOp = dyn_cast<Operator>(Ptr);
if (PtrOp == 0 || Ptr->getType()->isVectorTy())
return Ptr;
@@ -1768,7 +1777,7 @@ uint64_t llvm::GetStringLength(Value *V) {
}
Value *
-llvm::GetUnderlyingObject(Value *V, const TargetData *TD, unsigned MaxLookup) {
+llvm::GetUnderlyingObject(Value *V, const DataLayout *TD, unsigned MaxLookup) {
if (!V->getType()->isPointerTy())
return V;
for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) {
@@ -1799,7 +1808,7 @@ llvm::GetUnderlyingObject(Value *V, const TargetData *TD, unsigned MaxLookup) {
void
llvm::GetUnderlyingObjects(Value *V,
SmallVectorImpl<Value *> &Objects,
- const TargetData *TD,
+ const DataLayout *TD,
unsigned MaxLookup) {
SmallPtrSet<Value *, 4> Visited;
SmallVector<Value *, 4> Worklist;
@@ -1844,7 +1853,7 @@ bool llvm::onlyUsedByLifetimeMarkers(const Value *V) {
}
bool llvm::isSafeToSpeculativelyExecute(const Value *V,
- const TargetData *TD) {
+ const DataLayout *TD) {
const Operator *Inst = dyn_cast<Operator>(V);
if (!Inst)
return false;
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 6e61665443..2ad0010fd1 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -525,6 +525,8 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(msp430_intrcc);
KEYWORD(ptx_kernel);
KEYWORD(ptx_device);
+ KEYWORD(spir_kernel);
+ KEYWORD(spir_func);
KEYWORD(cc);
KEYWORD(c);
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 66a8e17e11..86bc7aced1 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -916,48 +916,49 @@ bool LLParser::ParseOptionalAddrSpace(unsigned &AddrSpace) {
/// ParseOptionalAttrs - Parse a potentially empty attribute list. AttrKind
/// indicates what kind of attribute list this is: 0: function arg, 1: result,
/// 2: function attr.
-bool LLParser::ParseOptionalAttrs(Attributes &Attrs, unsigned AttrKind) {
- Attrs = Attribute::None;
+bool LLParser::ParseOptionalAttrs(Attributes::Builder &B, unsigned AttrKind) {
LocTy AttrLoc = Lex.getLoc();
bool HaveError = false;
+ B.clear();
+
while (1) {
lltok::Kind Token = Lex.getKind();
switch (Token) {
default: // End of attributes.
return HaveError;
- case lltok::kw_zeroext: Attrs |= Attribute::ZExt; break;
- case lltok::kw_signext: Attrs |= Attribute::SExt; break;
- case lltok::kw_inreg: Attrs |= Attribute::InReg; break;
- case lltok::kw_sret: Attrs |= Attribute::StructRet; break;
- case lltok::kw_noalias: Attrs |= Attribute::NoAlias; break;
- case lltok::kw_nocapture: Attrs |= Attribute::NoCapture; break;
- case lltok::kw_byval: Attrs |= Attribute::ByVal; break;
- case lltok::kw_nest: Attrs |= Attribute::Nest; break;
-
- case lltok::kw_noreturn: Attrs |= Attribute::NoReturn; break;
- case lltok::kw_nounwind: Attrs |= Attribute::NoUnwind; break;
- case lltok::kw_uwtable: Attrs |= Attribute::UWTable; break;
- case lltok::kw_returns_twice: Attrs |= Attribute::ReturnsTwice; break;
- case lltok::kw_noinline: Attrs |= Attribute::NoInline; break;
- case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break;
- case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break;
- case lltok::kw_inlinehint: Attrs |= Attribute::InlineHint; break;
- case lltok::kw_alwaysinline: Attrs |= Attribute::AlwaysInline; break;
- case lltok::kw_optsize: Attrs |= Attribute::OptimizeForSize; break;
- case lltok::kw_ssp: Attrs |= Attribute::StackProtect; break;
- case lltok::kw_sspreq: Attrs |= Attribute::StackProtectReq; break;
- case lltok::kw_noredzone: Attrs |= Attribute::NoRedZone; break;
- case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break;
- case lltok::kw_naked: Attrs |= Attribute::Naked; break;
- case lltok::kw_nonlazybind: Attrs |= Attribute::NonLazyBind; break;
- case lltok::kw_address_safety: Attrs |= Attribute::AddressSafety; break;
+ case lltok::kw_zeroext: B.addAttribute(Attributes::ZExt); break;
+ case lltok::kw_signext: B.addAttribute(Attributes::SExt); break;
+ case lltok::kw_inreg: B.addAttribute(Attributes::InReg); break;
+ case lltok::kw_sret: B.addAttribute(Attributes::StructRet); break;
+ case lltok::kw_noalias: B.addAttribute(Attributes::NoAlias); break;
+ case lltok::kw_nocapture: B.addAttribute(Attributes::NoCapture); break;
+ case lltok::kw_byval: B.addAttribute(Attributes::ByVal); break;
+ case lltok::kw_nest: B.addAttribute(Attributes::Nest); break;
+
+ case lltok::kw_noreturn: B.addAttribute(Attributes::NoReturn); break;
+ case lltok::kw_nounwind: B.addAttribute(Attributes::NoUnwind); break;
+ case lltok::kw_uwtable: B.addAttribute(Attributes::UWTable); break;
+ case lltok::kw_returns_twice: B.addAttribute(Attributes::ReturnsTwice); break;
+ case lltok::kw_noinline: B.addAttribute(Attributes::NoInline); break;
+ case lltok::kw_readnone: B.addAttribute(Attributes::ReadNone); break;
+ case lltok::kw_readonly: B.addAttribute(Attributes::ReadOnly); break;
+ case lltok::kw_inlinehint: B.addAttribute(Attributes::InlineHint); break;
+ case lltok::kw_alwaysinline: B.addAttribute(Attributes::AlwaysInline); break;
+ case lltok::kw_optsize: B.addAttribute(Attributes::OptimizeForSize); break;
+ case lltok::kw_ssp: B.addAttribute(Attributes::StackProtect); break;
+ case lltok::kw_sspreq: B.addAttribute(Attributes::StackProtectReq); break;
+ case lltok::kw_noredzone: B.addAttribute(Attributes::NoRedZone); break;
+ case lltok::kw_noimplicitfloat: B.addAttribute(Attributes::NoImplicitFloat); break;
+ case lltok::kw_naked: B.addAttribute(Attributes::Naked); break;
+ case lltok::kw_nonlazybind: B.addAttribute(Attributes::NonLazyBind); break;
+ case lltok::kw_address_safety: B.addAttribute(Attributes::AddressSafety); break;
case lltok::kw_alignstack: {
unsigned Alignment;
if (ParseOptionalStackAlignment(Alignment))
return true;
- Attrs |= Attributes::constructStackAlignmentFromInt(Alignment);
+ B.addStackAlignmentAttr(Alignment);
continue;
}
@@ -965,7 +966,7 @@ bool LLParser::ParseOptionalAttrs(Attributes &Attrs, unsigned AttrKind) {
unsigned Alignment;
if (ParseOptionalAlignment(Alignment))
return true;
- Attrs |= Attributes::constructAlignmentFromInt(Alignment);
+ B.addAlignmentAttr(Alignment);
continue;
}
@@ -1101,6 +1102,8 @@ bool LLParser::ParseOptionalVisibility(unsigned &Res) {
/// ::= 'msp430_intrcc'
/// ::= 'ptx_kernel'
/// ::= 'ptx_device'
+/// ::= 'spir_func'
+/// ::= 'spir_kernel'
/// ::= 'cc' UINT
///
bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
@@ -1118,6 +1121,8 @@ bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
case lltok::kw_msp430_intrcc: CC = CallingConv::MSP430_INTR; break;
case lltok::kw_ptx_kernel: CC = CallingConv::PTX_Kernel; break;
case lltok::kw_ptx_device: CC = CallingConv::PTX_Device; break;
+ case lltok::kw_spir_kernel: CC = CallingConv::SPIR_KERNEL; break;
+ case lltok::kw_spir_func: CC = CallingConv::SPIR_FUNC; break;
case lltok::kw_cc: {
unsigned ArbitraryCC;
Lex.Lex();
@@ -1430,16 +1435,15 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
// Parse the argument.
LocTy ArgLoc;
Type *ArgTy = 0;
- Attributes ArgAttrs1;
- Attributes ArgAttrs2;
+ Attributes::Builder ArgAttrs;
Value *V;
if (ParseType(ArgTy, ArgLoc))
return true;
// Otherwise, handle normal operands.
- if (ParseOptionalAttrs(ArgAttrs1, 0) || ParseValue(ArgTy, V, PFS))
+ if (ParseOptionalAttrs(ArgAttrs, 0) || ParseValue(ArgTy, V, PFS))
return true;
- ArgList.push_back(ParamInfo(ArgLoc, V, ArgAttrs1|ArgAttrs2));
+ ArgList.push_back(ParamInfo(ArgLoc, V, Attributes::get(ArgAttrs)));
}
Lex.Lex(); // Lex the ')'.
@@ -1471,7 +1475,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
} else {
LocTy TypeLoc = Lex.getLoc();
Type *ArgTy = 0;
- Attributes Attrs;
+ Attributes::Builder Attrs;
std::string Name;
if (ParseType(ArgTy) ||
@@ -1488,7 +1492,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
if (!FunctionType::isValidArgumentType(ArgTy))
return Error(TypeLoc, "invalid type for function argument");
- ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name));
+ ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attributes::get(Attrs), Name));
while (EatIfPresent(lltok::comma)) {
// Handle ... at end of arg list.
@@ -1514,7 +1518,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
if (!ArgTy->isFirstClassType())
return Error(TypeLoc, "invalid type for function argument");
- ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name));
+ ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attributes::get(Attrs), Name));
}
}
@@ -2668,7 +2672,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
unsigned Linkage;
unsigned Visibility;
- Attributes RetAttrs;
+ Attributes::Builder RetAttrs;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc = Lex.getLoc();
@@ -2732,7 +2736,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
SmallVector<ArgInfo, 8> ArgList;
bool isVarArg;
- Attributes FuncAttrs;
+ Attributes::Builder FuncAttrs;
std::string Section;
unsigned Alignment;
std::string GC;
@@ -2751,9 +2755,9 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
return true;
// If the alignment was parsed as an attribute, move to the alignment field.
- if (FuncAttrs & Attribute::Alignment) {
+ if (FuncAttrs.hasAlignmentAttr()) {
Alignment = FuncAttrs.getAlignment();
- FuncAttrs &= ~Attribute::Alignment;
+ FuncAttrs.removeAttribute(Attributes::Alignment);
}
// Okay, if we got here, the function is syntactically valid. Convert types
@@ -2762,7 +2766,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
SmallVector<AttributeWithIndex, 8> Attrs;
if (RetAttrs.hasAttributes())
- Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
+ Attrs.push_back(AttributeWithIndex::get(0, Attributes::get(RetAttrs)));
for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
ParamTypeList.push_back(ArgList[i].Ty);
@@ -2771,11 +2775,12 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
}
if (FuncAttrs.hasAttributes())
- Attrs.push_back(AttributeWithIndex::get(~0, FuncAttrs));
+ Attrs.push_back(AttributeWithIndex::get(~0, Attributes::get(FuncAttrs)));
AttrListPtr PAL = AttrListPtr::get(Attrs);
- if (PAL.paramHasAttr(1, Attribute::StructRet) && !RetType->isVoidTy())
+ if (PAL.getParamAttributes(1).hasAttribute(Attributes::StructRet) &&
+ !RetType->isVoidTy())
return Error(RetTypeLoc, "functions with 'sret' argument must return void");
FunctionType *FT =
@@ -3243,7 +3248,7 @@ bool LLParser::ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) {
/// OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue
bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
LocTy CallLoc = Lex.getLoc();
- Attributes RetAttrs, FnAttrs;
+ Attributes::Builder RetAttrs, FnAttrs;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc;
@@ -3289,7 +3294,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
// Set up the Attributes for the function.
SmallVector<AttributeWithIndex, 8> Attrs;
if (RetAttrs.hasAttributes())
- Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
+ Attrs.push_back(AttributeWithIndex::get(0, Attributes::get(RetAttrs)));
SmallVector<Value*, 8> Args;
@@ -3317,7 +3322,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
return Error(CallLoc, "not enough parameters specified for call");
if (FnAttrs.hasAttributes())
- Attrs.push_back(AttributeWithIndex::get(~0, FnAttrs));
+ Attrs.push_back(AttributeWithIndex::get(~0, Attributes::get(FnAttrs)));
// Finish off the Attributes and check them
AttrListPtr PAL = AttrListPtr::get(Attrs);
@@ -3642,7 +3647,7 @@ bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
/// ParameterList OptionalAttrs
bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
bool isTail) {
- Attributes RetAttrs, FnAttrs;
+ Attributes::Builder RetAttrs, FnAttrs;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc;
@@ -3685,7 +3690,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
// Set up the Attributes for the function.
SmallVector<AttributeWithIndex, 8> Attrs;
if (RetAttrs.hasAttributes())
- Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
+ Attrs.push_back(AttributeWithIndex::get(0, Attributes::get(RetAttrs)));
SmallVector<Value*, 8> Args;
@@ -3713,7 +3718,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
return Error(CallLoc, "not enough parameters specified for call");
if (FnAttrs.hasAttributes())
- Attrs.push_back(AttributeWithIndex::get(~0, FnAttrs));
+ Attrs.push_back(AttributeWithIndex::get(~0, Attributes::get(FnAttrs)));
// Finish off the Attributes and check them
AttrListPtr PAL = AttrListPtr::get(Attrs);
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index 257c726229..671eaf6429 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -175,7 +175,7 @@ namespace llvm {
bool ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM);
bool ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM);
bool ParseOptionalAddrSpace(unsigned &AddrSpace);
- bool ParseOptionalAttrs(Attributes &Attrs, unsigned AttrKind);
+ bool ParseOptionalAttrs(Attributes::Builder &Attrs, unsigned AttrKind);
bool ParseOptionalLinkage(unsigned &Linkage, bool &HasLinkage);
bool ParseOptionalLinkage(unsigned &Linkage) {
bool HasLinkage; return ParseOptionalLinkage(Linkage, HasLinkage);
diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h
index 37cbf3003e..0859f6a288 100644
--- a/lib/AsmParser/LLToken.h
+++ b/lib/AsmParser/LLToken.h
@@ -81,6 +81,7 @@ namespace lltok {
kw_arm_apcscc, kw_arm_aapcscc, kw_arm_aapcs_vfpcc,
kw_msp430_intrcc,
kw_ptx_kernel, kw_ptx_device,
+ kw_spir_kernel, kw_spir_func,
kw_signext,
kw_zeroext,
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index c3bffc5d63..64cedd212d 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -482,7 +482,7 @@ bool BitcodeReader::ParseAttributeBlock() {
}
for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
- if (Attributes(Record[i+1]) != Attribute::None)
+ if (Attributes(Record[i+1]).hasAttributes())
Attrs.push_back(AttributeWithIndex::get(Record[i],
Attributes(Record[i+1])));
}
diff --git a/lib/CodeGen/Analysis.cpp b/lib/CodeGen/Analysis.cpp
index 1f3f5a5f38..d7214e8b58 100644
--- a/lib/CodeGen/Analysis.cpp
+++ b/lib/CodeGen/Analysis.cpp
@@ -21,7 +21,7 @@
#include "llvm/Module.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/ErrorHandling.h"
@@ -79,7 +79,7 @@ void llvm::ComputeValueVTs(const TargetLowering &TLI, Type *Ty,
uint64_t StartingOffset) {
// Given a struct type, recursively traverse the elements.
if (StructType *STy = dyn_cast<StructType>(Ty)) {
- const StructLayout *SL = TLI.getTargetData()->getStructLayout(STy);
+ const StructLayout *SL = TLI.getDataLayout()->getStructLayout(STy);
for (StructType::element_iterator EB = STy->element_begin(),
EI = EB,
EE = STy->element_end();
@@ -91,7 +91,7 @@ void llvm::ComputeValueVTs(const TargetLowering &TLI, Type *Ty,
// Given an array type, recursively traverse the elements.
if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
Type *EltTy = ATy->getElementType();
- uint64_t EltSize = TLI.getTargetData()->getTypeAllocSize(EltTy);
+ uint64_t EltSize = TLI.getDataLayout()->getTypeAllocSize(EltTy);
for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i)
ComputeValueVTs(TLI, EltTy, ValueVTs, Offsets,
StartingOffset + i * EltSize);
@@ -318,7 +318,8 @@ bool llvm::isInTailCallPosition(ImmutableCallSite CS, Attributes CalleeRetAttr,
return false;
// It's not safe to eliminate the sign / zero extension of the return value.
- if (CallerRetAttr.hasZExtAttr() || CallerRetAttr.hasSExtAttr())
+ if (CallerRetAttr.hasAttribute(Attributes::ZExt) ||
+ CallerRetAttr.hasAttribute(Attributes::SExt))
return false;
// Otherwise, make sure the unmodified return value of I is the return value.
@@ -358,7 +359,8 @@ bool llvm::isInTailCallPosition(SelectionDAG &DAG, SDNode *Node,
return false;
// It's not safe to eliminate the sign / zero extension of the return value.
- if (CallerRetAttr.hasZExtAttr() || CallerRetAttr.hasSExtAttr())
+ if (CallerRetAttr.hasAttribute(Attributes::ZExt) ||
+ CallerRetAttr.hasAttribute(Attributes::SExt))
return false;
// Check if the only use is a function return node.
diff --git a/lib/CodeGen/AsmPrinter/ARMException.cpp b/lib/CodeGen/AsmPrinter/ARMException.cpp
index bf5d8c4880..b2ebf04e51 100644
--- a/lib/CodeGen/AsmPrinter/ARMException.cpp
+++ b/lib/CodeGen/AsmPrinter/ARMException.cpp
@@ -24,7 +24,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index d506d7e507..b4f0b174b5 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -33,7 +33,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
@@ -67,7 +67,7 @@ static gcp_map_type &getGCMap(void *&P) {
/// getGVAlignmentLog2 - Return the alignment to use for the specified global
/// value in log2 form. This rounds up to the preferred alignment if possible
/// and legal.
-static unsigned getGVAlignmentLog2(const GlobalValue *GV, const TargetData &TD,
+static unsigned getGVAlignmentLog2(const GlobalValue *GV, const DataLayout &TD,
unsigned InBits = 0) {
unsigned NumBits = 0;
if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
@@ -131,9 +131,9 @@ const TargetLoweringObjectFile &AsmPrinter::getObjFileLowering() const {
}
-/// getTargetData - Return information about data layout.
-const TargetData &AsmPrinter::getTargetData() const {
- return *TM.getTargetData();
+/// getDataLayout - Return information about data layout.
+const DataLayout &AsmPrinter::getDataLayout() const {
+ return *TM.getDataLayout();
}
/// getCurrentSection() - Return the current section we are emitting to.
@@ -165,7 +165,7 @@ bool AsmPrinter::doInitialization(Module &M) {
const_cast<TargetLoweringObjectFile&>(getObjFileLowering())
.Initialize(OutContext, TM);
- Mang = new Mangler(OutContext, *TM.getTargetData());
+ Mang = new Mangler(OutContext, *TM.getDataLayout());
// Allow the target to emit any magic that it wants at the start of the file.
EmitStartOfAsmFile(M);
@@ -296,7 +296,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM);
- const TargetData *TD = TM.getTargetData();
+ const DataLayout *TD = TM.getDataLayout();
uint64_t Size = TD->getTypeAllocSize(GV->getType()->getElementType());
// If the alignment is specified, we *must* obey it. Overaligning a global
@@ -1036,7 +1036,7 @@ void AsmPrinter::EmitConstantPool() {
Kind = SectionKind::getReadOnlyWithRelLocal();
break;
case 0:
- switch (TM.getTargetData()->getTypeAllocSize(CPE.getType())) {
+ switch (TM.getDataLayout()->getTypeAllocSize(CPE.getType())) {
case 4: Kind = SectionKind::getMergeableConst4(); break;
case 8: Kind = SectionKind::getMergeableConst8(); break;
case 16: Kind = SectionKind::getMergeableConst16();break;
@@ -1082,7 +1082,7 @@ void AsmPrinter::EmitConstantPool() {
OutStreamer.EmitFill(NewOffset - Offset, 0/*fillval*/, 0/*addrspace*/);
Type *Ty = CPE.getType();
- Offset = NewOffset + TM.getTargetData()->getTypeAllocSize(Ty);
+ Offset = NewOffset + TM.getDataLayout()->getTypeAllocSize(Ty);
OutStreamer.EmitLabel(GetCPISymbol(CPI));
if (CPE.isMachineConstantPoolEntry())
@@ -1138,7 +1138,7 @@ void AsmPrinter::EmitJumpTableInfo() {
JTInDiffSection = true;
}
- EmitAlignment(Log2_32(MJTI->getEntryAlignment(*TM.getTargetData())));
+ EmitAlignment(Log2_32(MJTI->getEntryAlignment(*TM.getDataLayout())));
// Jump tables in code sections are marked with a data_region directive
// where that's supported.
@@ -1254,7 +1254,7 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
assert(Value && "Unknown entry kind!");
- unsigned EntrySize = MJTI->getEntrySize(*TM.getTargetData());
+ unsigned EntrySize = MJTI->getEntrySize(*TM.getDataLayout());
OutStreamer.EmitValue(Value, EntrySize, /*addrspace*/0);
}
@@ -1355,7 +1355,7 @@ void AsmPrinter::EmitXXStructorList(const Constant *List, bool isCtor) {
}
// Emit the function pointers in the target-specific order
- const TargetData *TD = TM.getTargetData();
+ const DataLayout *TD = TM.getDataLayout();
unsigned Align = Log2_32(TD->getPointerPrefAlignment());
std::stable_sort(Structors.begin(), Structors.end(), priority_order);
for (unsigned i = 0, e = Structors.size(); i != e; ++i) {
@@ -1471,7 +1471,7 @@ void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
// if required for correctness.
//
void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV) const {
- if (GV) NumBits = getGVAlignmentLog2(GV, *TM.getTargetData(), NumBits);
+ if (GV) NumBits = getGVAlignmentLog2(GV, *TM.getDataLayout(), NumBits);
if (NumBits == 0) return; // 1-byte aligned: no need to emit alignment.
@@ -1510,10 +1510,10 @@ static const MCExpr *lowerConstant(const Constant *CV, AsmPrinter &AP) {
switch (CE->getOpcode()) {
default:
// If the code isn't optimized, there may be outstanding folding
- // opportunities. Attempt to fold the expression using TargetData as a
+ // opportunities. Attempt to fold the expression using DataLayout as a
// last resort before giving up.
if (Constant *C =
- ConstantFoldConstantExpression(CE, AP.TM.getTargetData()))
+ ConstantFoldConstantExpression(CE, AP.TM.getDataLayout()))
if (C != CE)
return lowerConstant(C, AP);
@@ -1527,7 +1527,7 @@ static const MCExpr *lowerConstant(const Constant *CV, AsmPrinter &AP) {
report_fatal_error(OS.str());
}
case Instruction::GetElementPtr: {
- const TargetData &TD = *AP.TM.getTargetData();
+ const DataLayout &TD = *AP.TM.getDataLayout();
// Generate a symbolic expression for the byte address
const Constant *PtrVal = CE->getOperand(0);
SmallVector<Value*, 8> IdxVec(CE->op_begin()+1, CE->op_end());
@@ -1556,7 +1556,7 @@ static const MCExpr *lowerConstant(const Constant *CV, AsmPrinter &AP) {
return lowerConstant(CE->getOperand(0), AP);
case Instruction::IntToPtr: {
- const TargetData &TD = *AP.TM.getTargetData();
+ const DataLayout &TD = *AP.TM.getDataLayout();
// Handle casts to pointers by changing them into casts to the appropriate
// integer type. This promotes constant folding and simplifies this code.
Constant *Op = CE->getOperand(0);
@@ -1566,7 +1566,7 @@ static const MCExpr *lowerConstant(const Constant *CV, AsmPrinter &AP) {
}
case Instruction::PtrToInt: {
- const TargetData &TD = *AP.TM.getTargetData();
+ const DataLayout &TD = *AP.TM.getDataLayout();
// Support only foldable casts to/from pointers that can be eliminated by
// changing the pointer to the appropriately sized integer type.
Constant *Op = CE->getOperand(0);
@@ -1640,7 +1640,7 @@ static int isRepeatedByteSequence(const Value *V, TargetMachine &TM) {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
if (CI->getBitWidth() > 64) return -1;
- uint64_t Size = TM.getTargetData()->getTypeAllocSize(V->getType());
+ uint64_t Size = TM.getDataLayout()->getTypeAllocSize(V->getType());
uint64_t Value = CI->getZExtValue();
// Make sure the constant is at least 8 bits long and has a power
@@ -1684,7 +1684,7 @@ static void emitGlobalConstantDataSequential(const ConstantDataSequential *CDS,
// See if we can aggregate this into a .fill, if so, emit it as such.
int Value = isRepeatedByteSequence(CDS, AP.TM);
if (Value != -1) {
- uint64_t Bytes = AP.TM.getTargetData()->getTypeAllocSize(CDS->getType());
+ uint64_t Bytes = AP.TM.getDataLayout()->getTypeAllocSize(CDS->getType());
// Don't emit a 1-byte object as a .fill.
if (Bytes > 1)
return AP.OutStreamer.EmitFill(Bytes, Value, AddrSpace);
@@ -1734,7 +1734,7 @@ static void emitGlobalConstantDataSequential(const ConstantDataSequential *CDS,
}
}
- const TargetData &TD = *AP.TM.getTargetData();
+ const DataLayout &TD = *AP.TM.getDataLayout();
unsigned Size = TD.getTypeAllocSize(CDS->getType());
unsigned EmittedSize = TD.getTypeAllocSize(CDS->getType()->getElementType()) *
CDS->getNumElements();
@@ -1750,7 +1750,7 @@ static void emitGlobalConstantArray(const ConstantArray *CA, unsigned AddrSpace,
int Value = isRepeatedByteSequence(CA, AP.TM);
if (Value != -1) {
- uint64_t Bytes = AP.TM.getTargetData()->getTypeAllocSize(CA->getType());
+ uint64_t Bytes = AP.TM.getDataLayout()->getTypeAllocSize(CA->getType());
AP.OutStreamer.EmitFill(Bytes, Value, AddrSpace);
}
else {
@@ -1764,7 +1764,7 @@ static void emitGlobalConstantVector(const ConstantVector *CV,
for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i)
emitGlobalConstantImpl(CV->getOperand(i), AddrSpace, AP);
- const TargetData &TD = *AP.TM.getTargetData();
+ const DataLayout &TD = *AP.TM.getDataLayout();
unsigned Size = TD.getTypeAllocSize(CV->getType());
unsigned EmittedSize = TD.getTypeAllocSize(CV->getType()->getElementType()) *
CV->getType()->getNumElements();
@@ -1775,7 +1775,7 @@ static void emitGlobalConstantVector(const ConstantVector *CV,
static void emitGlobalConstantStruct(const ConstantStruct *CS,
unsigned AddrSpace, AsmPrinter &AP) {
// Print the fields in successive locations. Pad to align if needed!
- const TargetData *TD = AP.TM.getTargetData();
+ const DataLayout *TD = AP.TM.getDataLayout();
unsigned Size = TD->getTypeAllocSize(CS->getType());
const StructLayout *Layout = TD->getStructLayout(CS->getType());
uint64_t SizeSoFar = 0;
@@ -1855,7 +1855,7 @@ static void emitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
<< DoubleVal.convertToDouble() << '\n';
}
- if (AP.TM.getTargetData()->isBigEndian()) {
+ if (AP.TM.getDataLayout()->isBigEndian()) {
AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace);
AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace);
} else {
@@ -1864,7 +1864,7 @@ static void emitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
}
// Emit the tail padding for the long double.
- const TargetData &TD = *AP.TM.getTargetData();
+ const DataLayout &TD = *AP.TM.getDataLayout();
AP.OutStreamer.EmitZeros(TD.getTypeAllocSize(CFP->getType()) -
TD.getTypeStoreSize(CFP->getType()), AddrSpace);
return;
@@ -1876,7 +1876,7 @@ static void emitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
// API needed to prevent premature destruction.
APInt API = CFP->getValueAPF().bitcastToAPInt();
const uint64_t *p = API.getRawData();
- if (AP.TM.getTargetData()->isBigEndian()) {
+ if (AP.TM.getDataLayout()->isBigEndian()) {
AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace);
AP.OutStreamer.EmitIntValue(p[1], 8, AddrSpace);
} else {
@@ -1887,7 +1887,7 @@ static void emitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
static void emitGlobalConstantLargeInt(const ConstantInt *CI,
unsigned AddrSpace, AsmPrinter &AP) {
- const TargetData *TD = AP.TM.getTargetData();
+ const DataLayout *TD = AP.TM.getDataLayout();
unsigned BitWidth = CI->getBitWidth();
assert((BitWidth & 63) == 0 && "only support multiples of 64-bits");
@@ -1903,7 +1903,7 @@ static void emitGlobalConstantLargeInt(const ConstantInt *CI,
static void emitGlobalConstantImpl(const Constant *CV, unsigned AddrSpace,
AsmPrinter &AP) {
- const TargetData *TD = AP.TM.getTargetData();
+ const DataLayout *TD = AP.TM.getDataLayout();
uint64_t Size = TD->getTypeAllocSize(CV->getType());
if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV))
return AP.OutStreamer.EmitZeros(Size, AddrSpace);
@@ -1968,7 +1968,7 @@ static void emitGlobalConstantImpl(const Constant *CV, unsigned AddrSpace,
/// EmitGlobalConstant - Print a general LLVM constant to the .s file.
void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) {
- uint64_t Size = TM.getTargetData()->getTypeAllocSize(CV->getType());
+ uint64_t Size = TM.getDataLayout()->getTypeAllocSize(CV->getType());
if (Size)
emitGlobalConstantImpl(CV, AddrSpace, *this);
else if (MAI->hasSubsectionsViaSymbols()) {
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
index 90d511cbab..d94e1fe61b 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
@@ -18,7 +18,7 @@
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
@@ -112,7 +112,7 @@ unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
switch (Encoding & 0x07) {
default: llvm_unreachable("Invalid encoded value.");
- case dwarf::DW_EH_PE_absptr: return TM.getTargetData()->getPointerSize();
+ case dwarf::DW_EH_PE_absptr: return TM.getDataLayout()->getPointerSize();
case dwarf::DW_EH_PE_udata2: return 2;
case dwarf::DW_EH_PE_udata4: return 4;
case dwarf::DW_EH_PE_udata8: return 8;
diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp
index cfb0864d42..4d73b3c222 100644
--- a/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -17,7 +17,7 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -200,7 +200,7 @@ void DIEInteger::EmitValue(AsmPrinter *Asm, unsigned Form) const {
case dwarf::DW_FORM_udata: Asm->EmitULEB128(Integer); return;
case dwarf::DW_FORM_sdata: Asm->EmitSLEB128(Integer); return;
case dwarf::DW_FORM_addr:
- Size = Asm->getTargetData().getPointerSize(); break;
+ Size = Asm->getDataLayout().getPointerSize(); break;
default: llvm_unreachable("DIE Value form not supported yet");
}
Asm->OutStreamer.EmitIntValue(Integer, Size, 0/*addrspace*/);
@@ -222,7 +222,7 @@ unsigned DIEInteger::SizeOf(AsmPrinter *AP, unsigned Form) const {
case dwarf::DW_FORM_data8: return sizeof(int64_t);
case dwarf::DW_FORM_udata: return MCAsmInfo::getULEB128Size(Integer);
case dwarf::DW_FORM_sdata: return MCAsmInfo::getSLEB128Size(Integer);
- case dwarf::DW_FORM_addr: return AP->getTargetData().getPointerSize();
+ case dwarf::DW_FORM_addr: return AP->getDataLayout().getPointerSize();
default: llvm_unreachable("DIE Value form not supported yet");
}
}
@@ -249,7 +249,7 @@ void DIELabel::EmitValue(AsmPrinter *AP, unsigned Form) const {
unsigned DIELabel::SizeOf(AsmPrinter *AP, unsigned Form) const {
if (Form == dwarf::DW_FORM_data4) return 4;
if (Form == dwarf::DW_FORM_strp) return 4;
- return AP->getTargetData().getPointerSize();
+ return AP->getDataLayout().getPointerSize();
}
#ifndef NDEBUG
@@ -273,7 +273,7 @@ void DIEDelta::EmitValue(AsmPrinter *AP, unsigned Form) const {
unsigned DIEDelta::SizeOf(AsmPrinter *AP, unsigned Form) const {
if (Form == dwarf::DW_FORM_data4) return 4;
if (Form == dwarf::DW_FORM_strp) return 4;
- return AP->getTargetData().getPointerSize();
+ return AP->getDataLayout().getPointerSize();
}
#ifndef NDEBUG
diff --git a/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp b/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp
index 454a923c13..05e0f2fb63 100644
--- a/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp
@@ -133,8 +133,8 @@ void DwarfAccelTable::EmitHeader(AsmPrinter *Asm) {
}
}
-// Walk through and emit the buckets for the table. This will look
-// like a list of numbers of how many elements are in each bucket.
+// Walk through and emit the buckets for the table. Each index is
+// an offset into the list of hashes.
void DwarfAccelTable::EmitBuckets(AsmPrinter *Asm) {
unsigned index = 0;
for (size_t i = 0, e = Buckets.size(); i < e; ++i) {
diff --git a/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp b/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
index d975f1f97b..4fdd5ca252 100644
--- a/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
@@ -25,7 +25,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 0007f13e91..2b07dda31f 100644
--- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -22,7 +22,7 @@
#include "llvm/Instructions.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/Mangler.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
@@ -510,7 +510,7 @@ bool CompileUnit::addConstantFPValue(DIE *Die, const MachineOperand &MO) {
const char *FltPtr = (const char*)FltVal.getRawData();
int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte.
- bool LittleEndian = Asm->getTargetData().isLittleEndian();
+ bool LittleEndian = Asm->getDataLayout().isLittleEndian();
int Incr = (LittleEndian ? 1 : -1);
int Start = (LittleEndian ? 0 : NumBytes - 1);
int Stop = (LittleEndian ? NumBytes : -1);
@@ -552,7 +552,7 @@ bool CompileUnit::addConstantValue(DIE *Die, const ConstantInt *CI,
const uint64_t *Ptr64 = Val.getRawData();
int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte.
- bool LittleEndian = Asm->getTargetData().isLittleEndian();
+ bool LittleEndian = Asm->getDataLayout().isLittleEndian();
// Output the constant to DWARF one byte at a time.
for (int i = 0; i < NumBytes; i++) {
@@ -1227,7 +1227,7 @@ void CompileUnit::createGlobalVariableDIE(const MDNode *N) {
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
SmallVector<Value*, 3> Idx(CE->op_begin()+1, CE->op_end());
addUInt(Block, 0, dwarf::DW_FORM_udata,
- Asm->getTargetData().getIndexedOffset(Ptr->getType(), Idx));
+ Asm->getDataLayout().getIndexedOffset(Ptr->getType(), Idx));
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
}
@@ -1459,7 +1459,7 @@ DIE *CompileUnit::createMemberDIE(DIDerivedType DT) {
Offset -= FieldOffset;
// Maybe we need to work from the other end.
- if (Asm->getTargetData().isLittleEndian())
+ if (Asm->getDataLayout().isLittleEndian())
Offset = FieldSize - (Offset + Size);
addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index ee8a6f36e7..9982d39641 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -27,7 +27,7 @@
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
@@ -331,8 +331,8 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU,
if (ATy.isArtificial())
SPCU->addFlag(Arg, dwarf::DW_AT_artificial);
if (ATy.isObjectPointer())
- SPCU->addDIEEntry(SPDie, dwarf::DW_AT_object_pointer, dwarf::DW_FORM_ref4,
- Arg);
+ SPCU->addDIEEntry(SPDie, dwarf::DW_AT_object_pointer,
+ dwarf::DW_FORM_ref4, Arg);
SPDie->addChild(Arg);
}
DIE *SPDeclDie = SPDie;
@@ -384,7 +384,7 @@ DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU,
// DW_AT_ranges appropriately.
TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4,
DebugRangeSymbols.size()
- * Asm->getTargetData().getPointerSize());
+ * Asm->getDataLayout().getPointerSize());
for (SmallVector<InsnRange, 4>::const_iterator RI = Ranges.begin(),
RE = Ranges.end(); RI != RE; ++RI) {
DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first));
@@ -450,7 +450,7 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU,
// DW_AT_ranges appropriately.
TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4,
DebugRangeSymbols.size()
- * Asm->getTargetData().getPointerSize());
+ * Asm->getDataLayout().getPointerSize());
for (SmallVector<InsnRange, 4>::const_iterator RI = Ranges.begin(),
RE = Ranges.end(); RI != RE; ++RI) {
DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first));
@@ -1097,7 +1097,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
if (AbsVar)
AbsVar->setMInsn(MInsn);
- // Simple ranges that are fully coalesced.
+ // Simplify ranges that are fully coalesced.
if (History.size() <= 1 || (History.size() == 2 &&
MInsn->isIdenticalTo(History.back()))) {
RegVar->setMInsn(MInsn);
@@ -1350,7 +1350,7 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
// Coalesce identical entries at the end of History.
if (History.size() >= 2 &&
Prev->isIdenticalTo(History[History.size() - 2])) {
- DEBUG(dbgs() << "Coalesce identical DBG_VALUE entries:\n"
+ DEBUG(dbgs() << "Coalescing identical DBG_VALUE entries:\n"
<< "\t" << *Prev
<< "\t" << *History[History.size() - 2] << "\n");
History.pop_back();
@@ -1366,7 +1366,7 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
PrevMBB->getLastNonDebugInstr();
if (LastMI == PrevMBB->end()) {
// Drop DBG_VALUE for empty range.
- DEBUG(dbgs() << "Drop DBG_VALUE for empty range:\n"
+ DEBUG(dbgs() << "Dropping DBG_VALUE for empty range:\n"
<< "\t" << *Prev << "\n");
History.pop_back();
}
@@ -1383,9 +1383,10 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
if (!MI->isLabel())
AtBlockEntry = false;
- // First known non DBG_VALUE location marks beginning of function
- // body.
- if (PrologEndLoc.isUnknown() && !MI->getDebugLoc().isUnknown())
+ // First known non-DBG_VALUE and non-frame setup location marks
+ // the beginning of the function body.
+ if (!MI->getFlag(MachineInstr::FrameSetup) &&
+ (PrologEndLoc.isUnknown() && !MI->getDebugLoc().isUnknown()))
PrologEndLoc = MI->getDebugLoc();
// Check if the instruction clobbers any registers with debug vars.
@@ -1792,7 +1793,7 @@ void DwarfDebug::emitDebugInfo() {
Asm->EmitSectionOffset(Asm->GetTempSymbol("abbrev_begin"),
DwarfAbbrevSectionSym);
Asm->OutStreamer.AddComment("Address Size (in bytes)");
- Asm->EmitInt8(Asm->getTargetData().getPointerSize());
+ Asm->EmitInt8(Asm->getDataLayout().getPointerSize());
emitDIE(Die);
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_end", TheCU->getID()));
@@ -1838,14 +1839,14 @@ void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) {
Asm->EmitInt8(0);
Asm->OutStreamer.AddComment("Op size");
- Asm->EmitInt8(Asm->getTargetData().getPointerSize() + 1);
+ Asm->EmitInt8(Asm->getDataLayout().getPointerSize() + 1);
Asm->OutStreamer.AddComment("DW_LNE_set_address");
Asm->EmitInt8(dwarf::DW_LNE_set_address);
Asm->OutStreamer.AddComment("Section end label");
Asm->OutStreamer.EmitSymbolValue(Asm->GetTempSymbol("section_end",SectionEnd),
- Asm->getTargetData().getPointerSize(),
+ Asm->getDataLayout().getPointerSize(),
0/*AddrSpace*/);
// Mark end of matrix.
@@ -2074,7 +2075,7 @@ void DwarfDebug::emitDebugLoc() {
// Start the dwarf loc section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfLocSection());
- unsigned char Size = Asm->getTargetData().getPointerSize();
+ unsigned char Size = Asm->getDataLayout().getPointerSize();
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_loc", 0));
unsigned index = 1;
for (SmallVector<DotDebugLocEntry, 4>::iterator
@@ -2171,7 +2172,7 @@ void DwarfDebug::emitDebugRanges() {
// Start the dwarf ranges section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfRangesSection());
- unsigned char Size = Asm->getTargetData().getPointerSize();
+ unsigned char Size = Asm->getDataLayout().getPointerSize();
for (SmallVector<const MCSymbol *, 8>::iterator
I = DebugRangeSymbols.begin(), E = DebugRangeSymbols.end();
I != E; ++I) {
@@ -2229,7 +2230,7 @@ void DwarfDebug::emitDebugInlineInfo() {
Asm->OutStreamer.AddComment("Dwarf Version");
Asm->EmitInt16(dwarf::DWARF_VERSION);
Asm->OutStreamer.AddComment("Address Size (in bytes)");
- Asm->EmitInt8(Asm->getTargetData().getPointerSize());
+ Asm->EmitInt8(Asm->getDataLayout().getPointerSize());
for (SmallVector<const MDNode *, 4>::iterator I = InlinedSPNodes.begin(),
E = InlinedSPNodes.end(); I != E; ++I) {
@@ -2260,7 +2261,7 @@ void DwarfDebug::emitDebugInlineInfo() {
if (Asm->isVerbose()) Asm->OutStreamer.AddComment("low_pc");
Asm->OutStreamer.EmitSymbolValue(LI->first,
- Asm->getTargetData().getPointerSize(),0);
+ Asm->getDataLayout().getPointerSize(),0);
}
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp
index 70cc2e56b3..08fb6b3f52 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp
@@ -24,7 +24,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
@@ -417,7 +417,7 @@ void DwarfException::EmitExceptionTable() {
// that we're omitting that bit.
TTypeEncoding = dwarf::DW_EH_PE_omit;
// dwarf::DW_EH_PE_absptr
- TypeFormatSize = Asm->getTargetData().getPointerSize();
+ TypeFormatSize = Asm->getDataLayout().getPointerSize();
} else {
// Okay, we have actual filters or typeinfos to emit. As such, we need to
// pick a type encoding for them. We're about to emit a list of pointers to
diff --git a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
index 1153817677..f7c011968c 100644
--- a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
@@ -20,7 +20,7 @@
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Target/Mangler.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/SmallString.h"
@@ -91,7 +91,7 @@ void OcamlGCMetadataPrinter::beginAssembly(AsmPrinter &AP) {
/// either condition is detected in a function which uses the GC.
///
void OcamlGCMetadataPrinter::finishAssembly(AsmPrinter &AP) {
- unsigned IntPtrSize = AP.TM.getTargetData()->getPointerSize();
+ unsigned IntPtrSize = AP.TM.getDataLayout()->getPointerSize();
AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getTextSection());
EmitCamlGlobal(getModule(), AP, "code_end");
diff --git a/lib/CodeGen/AsmPrinter/Win64Exception.cpp b/lib/CodeGen/AsmPrinter/Win64Exception.cpp
index b83aa5ae3a..70742a8d2e 100644
--- a/lib/CodeGen/AsmPrinter/Win64Exception.cpp
+++ b/lib/CodeGen/AsmPrinter/Win64Exception.cpp
@@ -24,7 +24,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp
index 5494c0f784..90f6eec831 100644
--- a/lib/CodeGen/BranchFolding.cpp
+++ b/lib/CodeGen/BranchFolding.cpp
@@ -373,9 +373,8 @@ static unsigned ComputeCommonTailLength(MachineBasicBlock *MBB1,
if (I1 == MBB1->begin() && I2 != MBB2->begin()) {
--I2;
while (I2->isDebugValue()) {
- if (I2 == MBB2->begin()) {
+ if (I2 == MBB2->begin())
return TailLen;
- }
--I2;
}
++I2;
@@ -498,21 +497,19 @@ bool
BranchFolder::MergePotentialsElt::operator<(const MergePotentialsElt &o) const {
if (getHash() < o.getHash())
return true;
- else if (getHash() > o.getHash())
+ if (getHash() > o.getHash())
return false;
- else if (getBlock()->getNumber() < o.getBlock()->getNumber())
+ if (getBlock()->getNumber() < o.getBlock()->getNumber())
return true;
- else if (getBlock()->getNumber() > o.getBlock()->getNumber())
+ if (getBlock()->getNumber() > o.getBlock()->getNumber())
return false;
- else {
- // _GLIBCXX_DEBUG checks strict weak ordering, which involves comparing
- // an object with itself.
+ // _GLIBCXX_DEBUG checks strict weak ordering, which involves comparing
+ // an object with itself.
#ifndef _GLIBCXX_DEBUG
- llvm_unreachable("Predecessor appears twice");
+ llvm_unreachable("Predecessor appears twice");
#else
- return false;
+ return false;
#endif
- }
}
/// CountTerminators - Count the number of terminators in the given
@@ -590,7 +587,8 @@ static bool ProfitableToMerge(MachineBasicBlock *MBB1,
// instructions that would be deleted in the merge.
MachineFunction *MF = MBB1->getParent();
if (EffectiveTailLen >= 2 &&
- MF->getFunction()->getFnAttributes().hasOptimizeForSizeAttr() &&
+ MF->getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize) &&
(I1 == MBB1->begin() || I2 == MBB2->begin()))
return true;
diff --git a/lib/CodeGen/CallingConvLower.cpp b/lib/CodeGen/CallingConvLower.cpp
index 89de59a12a..2bfb185a8d 100644
--- a/lib/CodeGen/CallingConvLower.cpp
+++ b/lib/CodeGen/CallingConvLower.cpp
@@ -18,7 +18,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetLowering.h"
using namespace llvm;
diff --git a/lib/CodeGen/CodePlacementOpt.cpp b/lib/CodeGen/CodePlacementOpt.cpp
index 1009a1e29c..d8e06c33a6 100644
--- a/lib/CodeGen/CodePlacementOpt.cpp
+++ b/lib/CodeGen/CodePlacementOpt.cpp
@@ -373,7 +373,7 @@ bool CodePlacementOpt::OptimizeIntraLoopEdges(MachineFunction &MF) {
///
bool CodePlacementOpt::AlignLoops(MachineFunction &MF) {
const Function *F = MF.getFunction();
- if (F->getFnAttributes().hasOptimizeForSizeAttr())
+ if (F->getFnAttributes().hasAttribute(Attributes::OptimizeForSize))
return false;
unsigned Align = TLI->getPrefLoopAlignment();
diff --git a/lib/CodeGen/EarlyIfConversion.cpp b/lib/CodeGen/EarlyIfConversion.cpp
index c40c5acf11..7f28828a5d 100644
--- a/lib/CodeGen/EarlyIfConversion.cpp
+++ b/lib/CodeGen/EarlyIfConversion.cpp
@@ -31,9 +31,9 @@
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
-#include "llvm/MC/MCInstrItineraries.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
@@ -777,7 +777,8 @@ bool EarlyIfConverter::runOnMachineFunction(MachineFunction &MF) {
<< "********** Function: " << MF.getName() << '\n');
TII = MF.getTarget().getInstrInfo();
TRI = MF.getTarget().getRegisterInfo();
- SchedModel = MF.getTarget().getInstrItineraryData()->SchedModel;
+ SchedModel =
+ MF.getTarget().getSubtarget<TargetSubtargetInfo>().getSchedModel();
MRI = &MF.getRegInfo();
DomTree = &getAnalysis<MachineDominatorTree>();
Loops = getAnalysisIfAvailable<MachineLoopInfo>();
diff --git a/lib/CodeGen/ExecutionDepsFix.cpp b/lib/CodeGen/ExecutionDepsFix.cpp
index fee8e47b83..2311842671 100644
--- a/lib/CodeGen/ExecutionDepsFix.cpp
+++ b/lib/CodeGen/ExecutionDepsFix.cpp
@@ -626,9 +626,12 @@ void ExeDepsFix::visitSoftInstr(MachineInstr *mi, unsigned mask) {
}
dv->Instrs.push_back(mi);
- // Finally set all defs and non-collapsed uses to dv.
- for (unsigned i = 0, e = mi->getDesc().getNumOperands(); i != e; ++i) {
- MachineOperand &mo = mi->getOperand(i);
+ // Finally set all defs and non-collapsed uses to dv. We must iterate through
+ // all the operators, including imp-def ones.
+ for (MachineInstr::mop_iterator ii = mi->operands_begin(),
+ ee = mi->operands_end();
+ ii != ee; ++ii) {
+ MachineOperand &mo = *ii;
if (!mo.isReg()) continue;
int rx = regIndex(mo.getReg());
if (rx < 0) continue;
diff --git a/lib/CodeGen/IntrinsicLowering.cpp b/lib/CodeGen/IntrinsicLowering.cpp
index ba447ce6d4..eab10f2fd4 100644
--- a/lib/CodeGen/IntrinsicLowering.cpp
+++ b/lib/CodeGen/IntrinsicLowering.cpp
@@ -21,7 +21,7 @@
#include "llvm/Support/CallSite.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
using namespace llvm;
template <class ArgIt>
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index dca305849e..141f8edc83 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -1164,18 +1164,17 @@ private:
unsigned Reg = MO.getReg();
- // TODO: Currently we're skipping uses that are reserved or have no
- // interval, but we're not updating their kills. This should be
- // fixed.
- if (TargetRegisterInfo::isPhysicalRegister(Reg) && LIS.isReserved(Reg))
- continue;
+ // Don't track uses of reserved registers - they're not accurate.
+ // Reserved register live ranges look like a set of dead defs.
+ bool Resv =
+ TargetRegisterInfo::isPhysicalRegister(Reg) && LIS.isReserved(Reg);
// Collect ranges for register units. These live ranges are computed on
// demand, so just skip any that haven't been computed yet.
if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
for (MCRegUnitIterator Units(Reg, &TRI); Units.isValid(); ++Units)
if (LiveInterval *LI = LIS.getCachedRegUnit(*Units))
- collectRanges(MO, LI, Entering, Internal, Exiting, OldIdx);
+ collectRanges(MO, LI, Entering, Internal, Exiting, OldIdx, Resv);
} else {
// Collect ranges for individual virtual registers.
collectRanges(MO, &LIS.getInterval(Reg),
@@ -1186,8 +1185,8 @@ private:
void collectRanges(const MachineOperand &MO, LiveInterval *LI,
RangeSet &Entering, RangeSet &Internal, RangeSet &Exiting,
- SlotIndex OldIdx) {
- if (MO.readsReg()) {
+ SlotIndex OldIdx, bool IgnoreReads = false) {
+ if (!IgnoreReads && MO.readsReg()) {
LiveRange* LR = LI->getLiveRangeContaining(OldIdx);
if (LR != 0)
Entering.insert(std::make_pair(LI, LR));
diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp
index 22a64e5509..2e4496db00 100644
--- a/lib/CodeGen/MachineBasicBlock.cpp
+++ b/lib/CodeGen/MachineBasicBlock.cpp
@@ -21,7 +21,7 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Assembly/Writer.h"
diff --git a/lib/CodeGen/MachineBlockPlacement.cpp b/lib/CodeGen/MachineBlockPlacement.cpp
index 1f1ce671f5..cd3f19944e 100644
--- a/lib/CodeGen/MachineBlockPlacement.cpp
+++ b/lib/CodeGen/MachineBlockPlacement.cpp
@@ -1013,7 +1013,8 @@ void MachineBlockPlacement::buildCFGChains(MachineFunction &F) {
// exclusively on the loop info here so that we can align backedges in
// unnatural CFGs and backedges that were introduced purely because of the
// loop rotations done during this layout pass.
- if (F.getFunction()->getFnAttributes().hasOptimizeForSizeAttr())
+ if (F.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize))
return;
unsigned Align = TLI->getPrefLoopAlignment();
if (!Align)
diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp
index 34fbfe20f4..91d5211857 100644
--- a/lib/CodeGen/MachineFunction.cpp
+++ b/lib/CodeGen/MachineFunction.cpp
@@ -28,7 +28,7 @@
#include "llvm/MC/MCContext.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetFrameLowering.h"
@@ -59,13 +59,13 @@ MachineFunction::MachineFunction(const Function *F, const TargetMachine &TM,
RegInfo = 0;
MFInfo = 0;
FrameInfo = new (Allocator) MachineFrameInfo(*TM.getFrameLowering());
- if (Fn->getFnAttributes().hasStackAlignmentAttr())
+ if (Fn->getFnAttributes().hasAttribute(Attributes::StackAlignment))
FrameInfo->ensureMaxAlignment(Fn->getAttributes().
getFnAttributes().getStackAlignment());
- ConstantPool = new (Allocator) MachineConstantPool(TM.getTargetData());
+ ConstantPool = new (Allocator) MachineConstantPool(TM.getDataLayout());
Alignment = TM.getTargetLowering()->getMinFunctionAlignment();
// FIXME: Shouldn't use pref alignment if explicit alignment is set on Fn.
- if (!Fn->getFnAttributes().hasOptimizeForSizeAttr())
+ if (!Fn->getFnAttributes().hasAttribute(Attributes::OptimizeForSize))
Alignment = std::max(Alignment,
TM.getTargetLowering()->getPrefFunctionAlignment());
FunctionNumber = FunctionNum;
@@ -545,7 +545,7 @@ void MachineFrameInfo::dump(const MachineFunction &MF) const {
//===----------------------------------------------------------------------===//
/// getEntrySize - Return the size of each entry in the jump table.
-unsigned MachineJumpTableInfo::getEntrySize(const TargetData &TD) const {
+unsigned MachineJumpTableInfo::getEntrySize(const DataLayout &TD) const {
// The size of a jump table entry is 4 bytes unless the entry is just the
// address of a block, in which case it is the pointer size.
switch (getEntryKind()) {
@@ -564,7 +564,7 @@ unsigned MachineJumpTableInfo::getEntrySize(const TargetData &TD) const {
}
/// getEntryAlignment - Return the alignment of each entry in the jump table.
-unsigned MachineJumpTableInfo::getEntryAlignment(const TargetData &TD) const {
+unsigned MachineJumpTableInfo::getEntryAlignment(const DataLayout &TD) const {
// The alignment of a jump table entry is the alignment of int32 unless the
// entry is just the address of a block, in which case it is the pointer
// alignment.
@@ -670,7 +670,7 @@ MachineConstantPool::~MachineConstantPool() {
/// CanShareConstantPoolEntry - Test whether the given two constants
/// can be allocated the same constant pool entry.
static bool CanShareConstantPoolEntry(const Constant *A, const Constant *B,
- const TargetData *TD) {
+ const DataLayout *TD) {
// Handle the trivial case quickly.
if (A == B) return true;
@@ -694,7 +694,7 @@ static bool CanShareConstantPoolEntry(const Constant *A, const Constant *B,
// Try constant folding a bitcast of both instructions to an integer. If we
// get two identical ConstantInt's, then we are good to share them. We use
// the constant folding APIs to do this so that we get the benefit of
- // TargetData.
+ // DataLayout.
if (isa<PointerType>(A->getType()))
A = ConstantFoldInstOperands(Instruction::PtrToInt, IntTy,
const_cast<Constant*>(A), TD);
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp
index b71b37ac6f..e8885761db 100644
--- a/lib/CodeGen/MachineInstr.cpp
+++ b/lib/CodeGen/MachineInstr.cpp
@@ -540,20 +540,6 @@ void MachineInstr::addImplicitDefUseOperands() {
/// MachineInstr ctor - This constructor creates a MachineInstr and adds the
/// implicit operands. It reserves space for the number of operands specified by
/// the MCInstrDesc.
-MachineInstr::MachineInstr(const MCInstrDesc &tid, bool NoImp)
- : MCID(&tid), Flags(0), AsmPrinterFlags(0),
- NumMemRefs(0), MemRefs(0), Parent(0) {
- unsigned NumImplicitOps = 0;
- if (!NoImp)
- NumImplicitOps = MCID->getNumImplicitDefs() + MCID->getNumImplicitUses();
- Operands.reserve(NumImplicitOps + MCID->getNumOperands());
- if (!NoImp)
- addImplicitDefUseOperands();
- // Make sure that we get added to a machine basicblock
- LeakDetector::addGarbageObject(this);
-}
-
-/// MachineInstr ctor - As above, but with a DebugLoc.
MachineInstr::MachineInstr(const MCInstrDesc &tid, const DebugLoc dl,
bool NoImp)
: MCID(&tid), Flags(0), AsmPrinterFlags(0),
@@ -571,21 +557,6 @@ MachineInstr::MachineInstr(const MCInstrDesc &tid, const DebugLoc dl,
/// MachineInstr ctor - Work exactly the same as the ctor two above, except
/// that the MachineInstr is created and added to the end of the specified
/// basic block.
-MachineInstr::MachineInstr(MachineBasicBlock *MBB, const MCInstrDesc &tid)
- : MCID(&tid), Flags(0), AsmPrinterFlags(0),
- NumMemRefs(0), MemRefs(0), Parent(0) {
- assert(MBB && "Cannot use inserting ctor with null basic block!");
- unsigned NumImplicitOps =
- MCID->getNumImplicitDefs() + MCID->getNumImplicitUses();
- Operands.reserve(NumImplicitOps + MCID->getNumOperands());
- addImplicitDefUseOperands();
- // Make sure that we get added to a machine basicblock
- LeakDetector::addGarbageObject(this);
- MBB->push_back(this); // Add instruction to end of basic block!
-}
-
-/// MachineInstr ctor - As above, but with a DebugLoc.
-///
MachineInstr::MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl,
const MCInstrDesc &tid)
: MCID(&tid), Flags(0), AsmPrinterFlags(0),
diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp
index ea98b23c6d..005bf783e3 100644
--- a/lib/CodeGen/MachineModuleInfo.cpp
+++ b/lib/CodeGen/MachineModuleInfo.cpp
@@ -25,7 +25,7 @@
using namespace llvm;
using namespace llvm::dwarf;
-// Handle the Pass registration stuff necessary to use TargetData's.
+// Handle the Pass registration stuff necessary to use DataLayout's.
INITIALIZE_PASS(MachineModuleInfo, "machinemoduleinfo",
"Machine Module Information", false, false)
char MachineModuleInfo::ID = 0;
diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp
index d7ecec4163..27c1a67aa9 100644
--- a/lib/CodeGen/MachineScheduler.cpp
+++ b/lib/CodeGen/MachineScheduler.cpp
@@ -495,6 +495,7 @@ void ScheduleDAGMI::schedule() {
bool IsTopNode = false;
while (SUnit *SU = SchedImpl->pickNode(IsTopNode)) {
+ assert(!SU->isScheduled && "Node already scheduled");
if (!checkSchedLimit())
break;
@@ -1119,33 +1120,36 @@ SUnit *ConvergingScheduler::pickNode(bool &IsTopNode) {
return NULL;
}
SUnit *SU;
- if (ForceTopDown) {
- SU = Top.pickOnlyChoice();
- if (!SU) {
- SchedCandidate TopCand;
- CandResult TopResult =
- pickNodeFromQueue(Top.Available, DAG->getTopRPTracker(), TopCand);
- assert(TopResult != NoCand && "failed to find the first candidate");
- (void)TopResult;
- SU = TopCand.SU;
+ do {
+ if (ForceTopDown) {
+ SU = Top.pickOnlyChoice();
+ if (!SU) {
+ SchedCandidate TopCand;
+ CandResult TopResult =
+ pickNodeFromQueue(Top.Available, DAG->getTopRPTracker(), TopCand);
+ assert(TopResult != NoCand && "failed to find the first candidate");
+ (void)TopResult;
+ SU = TopCand.SU;
+ }
+ IsTopNode = true;
}
- IsTopNode = true;
- }
- else if (ForceBottomUp) {
- SU = Bot.pickOnlyChoice();
- if (!SU) {
- SchedCandidate BotCand;
- CandResult BotResult =
- pickNodeFromQueue(Bot.Available, DAG->getBotRPTracker(), BotCand);
- assert(BotResult != NoCand && "failed to find the first candidate");
- (void)BotResult;
- SU = BotCand.SU;
+ else if (ForceBottomUp) {
+ SU = Bot.pickOnlyChoice();
+ if (!SU) {
+ SchedCandidate BotCand;
+ CandResult BotResult =
+ pickNodeFromQueue(Bot.Available, DAG->getBotRPTracker(), BotCand);
+ assert(BotResult != NoCand && "failed to find the first candidate");
+ (void)BotResult;
+ SU = BotCand.SU;
+ }
+ IsTopNode = false;
}
- IsTopNode = false;
- }
- else {
- SU = pickNodeBidrectional(IsTopNode);
- }
+ else {
+ SU = pickNodeBidrectional(IsTopNode);
+ }
+ } while (SU->isScheduled);
+
if (SU->isTopReady())
Top.removeReady(SU);
if (SU->isBottomReady())
diff --git a/lib/CodeGen/MachineTraceMetrics.cpp b/lib/CodeGen/MachineTraceMetrics.cpp
index 1a3aa60918..b3abec76bc 100644
--- a/lib/CodeGen/MachineTraceMetrics.cpp
+++ b/lib/CodeGen/MachineTraceMetrics.cpp
@@ -14,9 +14,10 @@
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
-#include "llvm/MC/MCInstrItineraries.h"
+#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/PostOrderIterator.h"
@@ -50,9 +51,11 @@ bool MachineTraceMetrics::runOnMachineFunction(MachineFunction &Func) {
MF = &Func;
TII = MF->getTarget().getInstrInfo();
TRI = MF->getTarget().getRegisterInfo();
- ItinData = MF->getTarget().getInstrItineraryData();
MRI = &MF->getRegInfo();
Loops = &getAnalysis<MachineLoopInfo>();
+ const TargetSubtargetInfo &ST =
+ MF->getTarget().getSubtarget<TargetSubtargetInfo>();
+ SchedModel.init(*ST.getSchedModel(), &ST, TII);
BlockInfo.resize(MF->getNumBlockIDs());
return false;
}
@@ -674,7 +677,7 @@ computeCrossBlockCriticalPath(const TraceBlockInfo &TBI) {
const MachineInstr *DefMI = MTM.MRI->getVRegDef(LIR.Reg);
// Ignore dependencies outside the current trace.
const TraceBlockInfo &DefTBI = BlockInfo[DefMI->getParent()->getNumber()];
- if (!DefTBI.hasValidDepth() || DefTBI.Head != TBI.Head)
+ if (!DefTBI.isEarlierInSameTrace(TBI))
continue;
unsigned Len = LIR.Height + Cycles[DefMI].Depth;
MaxLen = std::max(MaxLen, Len);
@@ -737,16 +740,15 @@ computeInstrDepths(const MachineBasicBlock *MBB) {
const TraceBlockInfo&DepTBI =
BlockInfo[Dep.DefMI->getParent()->getNumber()];
// Ignore dependencies from outside the current trace.
- if (!DepTBI.hasValidDepth() || DepTBI.Head != TBI.Head)
+ if (!DepTBI.isEarlierInSameTrace(TBI))
continue;
assert(DepTBI.HasValidInstrDepths && "Inconsistent dependency");
unsigned DepCycle = Cycles.lookup(Dep.DefMI).Depth;
// Add latency if DefMI is a real instruction. Transients get latency 0.
if (!Dep.DefMI->isTransient())
- DepCycle += MTM.TII->computeOperandLatency(MTM.ItinData,
- Dep.DefMI, Dep.DefOp,
- UseMI, Dep.UseOp,
- /* FindMin = */ false);
+ DepCycle += MTM.SchedModel
+ .computeOperandLatency(Dep.DefMI, Dep.DefOp, UseMI, Dep.UseOp,
+ /* FindMin = */ false);
Cycle = std::max(Cycle, DepCycle);
}
// Remember the instruction depth.
@@ -769,7 +771,7 @@ computeInstrDepths(const MachineBasicBlock *MBB) {
// Height is the issue height computed from virtual register dependencies alone.
static unsigned updatePhysDepsUpwards(const MachineInstr *MI, unsigned Height,
SparseSet<LiveRegUnit> &RegUnits,
- const InstrItineraryData *ItinData,
+ const TargetSchedModel &SchedModel,
const TargetInstrInfo *TII,
const TargetRegisterInfo *TRI) {
SmallVector<unsigned, 8> ReadOps;
@@ -792,14 +794,10 @@ static unsigned updatePhysDepsUpwards(const MachineInstr *MI, unsigned Height,
unsigned DepHeight = I->Cycle;
if (!MI->isTransient()) {
// We may not know the UseMI of this dependency, if it came from the
- // live-in list.
- if (I->MI)
- DepHeight += TII->computeOperandLatency(ItinData,
- MI, MO.getOperandNo(),
- I->MI, I->Op);
- else
- // No UseMI. Just use the MI latency instead.
- DepHeight += TII->getInstrLatency(ItinData, MI);
+ // live-in list. SchedModel can handle a NULL UseMI.
+ DepHeight += SchedModel
+ .computeOperandLatency(MI, MO.getOperandNo(), I->MI, I->Op,
+ /* FindMin = */ false);
}
Height = std::max(Height, DepHeight);
// This regunit is dead above MI.
@@ -832,12 +830,12 @@ typedef DenseMap<const MachineInstr *, unsigned> MIHeightMap;
static bool pushDepHeight(const DataDep &Dep,
const MachineInstr *UseMI, unsigned UseHeight,
MIHeightMap &Heights,
- const InstrItineraryData *ItinData,
+ const TargetSchedModel &SchedModel,
const TargetInstrInfo *TII) {
// Adjust height by Dep.DefMI latency.
if (!Dep.DefMI->isTransient())
- UseHeight += TII->computeOperandLatency(ItinData, Dep.DefMI, Dep.DefOp,
- UseMI, Dep.UseOp);
+ UseHeight += SchedModel.computeOperandLatency(Dep.DefMI, Dep.DefOp,
+ UseMI, Dep.UseOp, false);
// Update Heights[DefMI] to be the maximum height seen.
MIHeightMap::iterator I;
@@ -951,7 +949,7 @@ computeInstrHeights(const MachineBasicBlock *MBB) {
unsigned Height = TBI.Succ ? Cycles.lookup(PHI).Height : 0;
DEBUG(dbgs() << "pred\t" << Height << '\t' << *PHI);
if (pushDepHeight(Deps.front(), PHI, Height,
- Heights, MTM.ItinData, MTM.TII))
+ Heights, MTM.SchedModel, MTM.TII))
addLiveIns(Deps.front().DefMI, Stack);
}
}
@@ -980,11 +978,11 @@ computeInstrHeights(const MachineBasicBlock *MBB) {
// There may also be regunit dependencies to include in the height.
if (HasPhysRegs)
Cycle = updatePhysDepsUpwards(MI, Cycle, RegUnits,
- MTM.ItinData, MTM.TII, MTM.TRI);
+ MTM.SchedModel, MTM.TII, MTM.TRI);
// Update the required height of any virtual registers read by MI.
for (unsigned i = 0, e = Deps.size(); i != e; ++i)
- if (pushDepHeight(Deps[i], MI, Cycle, Heights, MTM.ItinData, MTM.TII))
+ if (pushDepHeight(Deps[i], MI, Cycle, Heights, MTM.SchedModel, MTM.TII))
addLiveIns(Deps[i].DefMI, Stack);
InstrCycles &MICycles = Cycles[MI];
@@ -1054,10 +1052,8 @@ MachineTraceMetrics::Trace::getPHIDepth(const MachineInstr *PHI) const {
unsigned DepCycle = getInstrCycles(Dep.DefMI).Depth;
// Add latency if DefMI is a real instruction. Transients get latency 0.
if (!Dep.DefMI->isTransient())
- DepCycle += TE.MTM.TII->computeOperandLatency(TE.MTM.ItinData,
- Dep.DefMI, Dep.DefOp,
- PHI, Dep.UseOp,
- /* FindMin = */ false);
+ DepCycle += TE.MTM.SchedModel
+ .computeOperandLatency(Dep.DefMI, Dep.DefOp, PHI, Dep.UseOp, false);
return DepCycle;
}
@@ -1068,9 +1064,8 @@ unsigned MachineTraceMetrics::Trace::getResourceDepth(bool Bottom) const {
unsigned Instrs = TBI.InstrDepth;
if (Bottom)
Instrs += TE.MTM.BlockInfo[getBlockNum()].InstrCount;
- if (const MCSchedModel *Model = TE.MTM.ItinData->SchedModel)
- if (Model->IssueWidth != 0)
- return Instrs / Model->IssueWidth;
+ if (unsigned IW = TE.MTM.SchedModel.getIssueWidth())
+ Instrs /= IW;
// Assume issue width 1 without a schedule model.
return Instrs;
}
@@ -1080,9 +1075,8 @@ getResourceLength(ArrayRef<const MachineBasicBlock*> Extrablocks) const {
unsigned Instrs = TBI.InstrDepth + TBI.InstrHeight;
for (unsigned i = 0, e = Extrablocks.size(); i != e; ++i)
Instrs += TE.MTM.getResources(Extrablocks[i])->InstrCount;
- if (const MCSchedModel *Model = TE.MTM.ItinData->SchedModel)
- if (Model->IssueWidth != 0)
- return Instrs / Model->IssueWidth;
+ if (unsigned IW = TE.MTM.SchedModel.getIssueWidth())
+ Instrs /= IW;
// Assume issue width 1 without a schedule model.
return Instrs;
}
diff --git a/lib/CodeGen/MachineTraceMetrics.h b/lib/CodeGen/MachineTraceMetrics.h
index c5b86f31db..5f3b1d23e4 100644
--- a/lib/CodeGen/MachineTraceMetrics.h
+++ b/lib/CodeGen/MachineTraceMetrics.h
@@ -50,6 +50,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/TargetSchedule.h"
namespace llvm {
@@ -67,9 +68,9 @@ class MachineTraceMetrics : public MachineFunctionPass {
const MachineFunction *MF;
const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
- const InstrItineraryData *ItinData;
const MachineRegisterInfo *MRI;
const MachineLoopInfo *Loops;
+ TargetSchedModel SchedModel;
public:
class Ensemble;
@@ -164,6 +165,14 @@ public:
/// Invalidate height resources when a block below this one has changed.
void invalidateHeight() { InstrHeight = ~0u; HasValidInstrHeights = false; }
+ /// Determine if this block belongs to the same trace as TBI and comes
+ /// before it in the trace.
+ /// Also returns true when TBI == this.
+ bool isEarlierInSameTrace(const TraceBlockInfo &TBI) const {
+ return hasValidDepth() && TBI.hasValidDepth() &&
+ Head == TBI.Head && InstrDepth <= TBI.InstrDepth;
+ }
+
// Data-dependency-related information. Per-instruction depth and height
// are computed from data dependencies in the current trace, using
// itinerary data.
diff --git a/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp
index 82e1764d13..7c7d2c8045 100644
--- a/lib/CodeGen/Passes.cpp
+++ b/lib/CodeGen/Passes.cpp
@@ -49,8 +49,8 @@ static cl::opt<bool> DisableSSC("disable-ssc", cl::Hidden,
cl::desc("Disable Stack Slot Coloring"));
static cl::opt<bool> DisableMachineDCE("disable-machine-dce", cl::Hidden,
cl::desc("Disable Machine Dead Code Elimination"));
-static cl::opt<bool> EnableEarlyIfConversion("enable-early-ifcvt", cl::Hidden,
- cl::desc("Enable Early If-conversion"));
+static cl::opt<bool> DisableEarlyIfConversion("disable-early-ifcvt", cl::Hidden,
+ cl::desc("Disable Early If-conversion"));
static cl::opt<bool> DisableMachineLICM("disable-machine-licm", cl::Hidden,
cl::desc("Disable Machine LICM"));
static cl::opt<bool> DisableMachineCSE("disable-machine-cse", cl::Hidden,
@@ -161,7 +161,7 @@ static AnalysisID overridePass(AnalysisID StandardID, AnalysisID TargetID) {
return applyDisable(TargetID, DisableMachineDCE);
if (StandardID == &EarlyIfConverterID)
- return applyDisable(TargetID, !EnableEarlyIfConversion);
+ return applyDisable(TargetID, DisableEarlyIfConversion);
if (StandardID == &MachineLICMID)
return applyDisable(TargetID, DisableMachineLICM);
diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp
index 3a4125475e..86df0a127b 100644
--- a/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/lib/CodeGen/PrologEpilogInserter.cpp
@@ -96,7 +96,7 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) {
placeCSRSpillsAndRestores(Fn);
// Add the code to save and restore the callee saved registers
- if (!F->getFnAttributes().hasNakedAttr())
+ if (!F->getFnAttributes().hasAttribute(Attributes::Naked))
insertCSRSpillsAndRestores(Fn);
// Allow the target machine to make final modifications to the function
@@ -111,7 +111,7 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) {
// called functions. Because of this, calculateCalleeSavedRegisters()
// must be called before this function in order to set the AdjustsStack
// and MaxCallFrameSize variables.
- if (!F->getFnAttributes().hasNakedAttr())
+ if (!F->getFnAttributes().hasAttribute(Attributes::Naked))
insertPrologEpilogCode(Fn);
// Replace all MO_FrameIndex operands with physical register references
@@ -221,7 +221,7 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) {
return;
// In Naked functions we aren't going to save any registers.
- if (Fn.getFunction()->getFnAttributes().hasNakedAttr())
+ if (Fn.getFunction()->getFnAttributes().hasAttribute(Attributes::Naked))
return;
std::vector<CalleeSavedInfo> CSI;
diff --git a/lib/CodeGen/RegAllocPBQP.cpp b/lib/CodeGen/RegAllocPBQP.cpp
index fcdbce75d9..f2473681a5 100644
--- a/lib/CodeGen/RegAllocPBQP.cpp
+++ b/lib/CodeGen/RegAllocPBQP.cpp
@@ -231,7 +231,7 @@ std::auto_ptr<PBQPRAProblem> PBQPBuilder::build(MachineFunction *mf,
continue;
// vregLI crosses a regmask operand that clobbers preg.
- if (!regMaskOverlaps.empty() && !regMaskOverlaps.test(preg))
+ if (!regMaskOverlaps.empty() && regMaskOverlaps.test(preg))
continue;
// vregLI overlaps fixed regunit interference.
@@ -432,6 +432,7 @@ void RegAllocPBQP::getAnalysisUsage(AnalysisUsage &au) const {
au.addRequired<SlotIndexes>();
au.addPreserved<SlotIndexes>();
au.addRequired<LiveIntervals>();
+ au.addPreserved<LiveIntervals>();
//au.addRequiredID(SplitCriticalEdgesID);
if (customPassID)
au.addRequiredID(*customPassID);
@@ -443,6 +444,7 @@ void RegAllocPBQP::getAnalysisUsage(AnalysisUsage &au) const {
au.addRequired<MachineLoopInfo>();
au.addPreserved<MachineLoopInfo>();
au.addRequired<VirtRegMap>();
+ au.addPreserved<VirtRegMap>();
MachineFunctionPass::getAnalysisUsage(au);
}
diff --git a/lib/CodeGen/RegisterCoalescer.cpp b/lib/CodeGen/RegisterCoalescer.cpp
index f45072f1ac..1b46256baf 100644
--- a/lib/CodeGen/RegisterCoalescer.cpp
+++ b/lib/CodeGen/RegisterCoalescer.cpp
@@ -68,11 +68,6 @@ VerifyCoalescing("verify-coalescing",
cl::desc("Verify machine instrs before and after register coalescing"),
cl::Hidden);
-// Temporary option for testing new coalescer algo.
-static cl::opt<bool>
-NewCoalescer("new-coalescer", cl::Hidden, cl::init(true),
- cl::desc("Use new coalescer algorithm"));
-
namespace {
class RegisterCoalescer : public MachineFunctionPass,
private LiveRangeEdit::Delegate {
@@ -1733,11 +1728,15 @@ void JoinVals::pruneValues(JoinVals &Other,
// This value takes precedence over the value in Other.LI.
LIS->pruneValue(&Other.LI, Def, &EndPoints);
// Remove <def,read-undef> flags. This def is now a partial redef.
- if (!Def.isBlock())
+ if (!Def.isBlock()) {
for (MIOperands MO(Indexes->getInstructionFromIndex(Def));
MO.isValid(); ++MO)
if (MO->isReg() && MO->isDef() && MO->getReg() == LI.reg)
MO->setIsUndef(false);
+ // This value will reach instructions below, but we need to make sure
+ // the live range also reaches the instruction at Def.
+ EndPoints.push_back(Def);
+ }
DEBUG(dbgs() << "\t\tpruned " << PrintReg(Other.LI.reg) << " at " << Def
<< ": " << Other.LI << '\n');
break;
@@ -1840,348 +1839,10 @@ bool RegisterCoalescer::joinVirtRegs(CoalescerPair &CP) {
return true;
}
-/// ComputeUltimateVN - Assuming we are going to join two live intervals,
-/// compute what the resultant value numbers for each value in the input two
-/// ranges will be. This is complicated by copies between the two which can
-/// and will commonly cause multiple value numbers to be merged into one.
-///
-/// VN is the value number that we're trying to resolve. InstDefiningValue
-/// keeps track of the new InstDefiningValue assignment for the result
-/// LiveInterval. ThisFromOther/OtherFromThis are sets that keep track of
-/// whether a value in this or other is a copy from the opposite set.
-/// ThisValNoAssignments/OtherValNoAssignments keep track of value #'s that have
-/// already been assigned.
-///
-/// ThisFromOther[x] - If x is defined as a copy from the other interval, this
-/// contains the value number the copy is from.
-///
-static unsigned ComputeUltimateVN(VNInfo *VNI,
- SmallVector<VNInfo*, 16> &NewVNInfo,
- DenseMap<VNInfo*, VNInfo*> &ThisFromOther,
- DenseMap<VNInfo*, VNInfo*> &OtherFromThis,
- SmallVector<int, 16> &ThisValNoAssignments,
- SmallVector<int, 16> &OtherValNoAssignments) {
- unsigned VN = VNI->id;
-
- // If the VN has already been computed, just return it.
- if (ThisValNoAssignments[VN] >= 0)
- return ThisValNoAssignments[VN];
- assert(ThisValNoAssignments[VN] != -2 && "Cyclic value numbers");
-
- // If this val is not a copy from the other val, then it must be a new value
- // number in the destination.
- DenseMap<VNInfo*, VNInfo*>::iterator I = ThisFromOther.find(VNI);
- if (I == ThisFromOther.end()) {
- NewVNInfo.push_back(VNI);
- return ThisValNoAssignments[VN] = NewVNInfo.size()-1;
- }
- VNInfo *OtherValNo = I->second;
-
- // Otherwise, this *is* a copy from the RHS. If the other side has already
- // been computed, return it.
- if (OtherValNoAssignments[OtherValNo->id] >= 0)
- return ThisValNoAssignments[VN] = OtherValNoAssignments[OtherValNo->id];
-
- // Mark this value number as currently being computed, then ask what the
- // ultimate value # of the other value is.
- ThisValNoAssignments[VN] = -2;
- unsigned UltimateVN =
- ComputeUltimateVN(OtherValNo, NewVNInfo, OtherFromThis, ThisFromOther,
- OtherValNoAssignments, ThisValNoAssignments);
- return ThisValNoAssignments[VN] = UltimateVN;
-}
-
-
-// Find out if we have something like
-// A = X
-// B = X
-// if so, we can pretend this is actually
-// A = X
-// B = A
-// which allows us to coalesce A and B.
-// VNI is the definition of B. LR is the life range of A that includes
-// the slot just before B. If we return true, we add "B = X" to DupCopies.
-// This implies that A dominates B.
-static bool RegistersDefinedFromSameValue(LiveIntervals &li,
- const TargetRegisterInfo &tri,
- CoalescerPair &CP,
- VNInfo *VNI,
- VNInfo *OtherVNI,
- SmallVector<MachineInstr*, 8> &DupCopies) {
- // FIXME: This is very conservative. For example, we don't handle
- // physical registers.
-
- MachineInstr *MI = li.getInstructionFromIndex(VNI->def);
-
- if (!MI || CP.isPartial() || CP.isPhys())
- return false;
-
- unsigned A = CP.getDstReg();
- if (!TargetRegisterInfo::isVirtualRegister(A))
- return false;
-
- unsigned B = CP.getSrcReg();
- if (!TargetRegisterInfo::isVirtualRegister(B))
- return false;
-
- MachineInstr *OtherMI = li.getInstructionFromIndex(OtherVNI->def);
- if (!OtherMI)
- return false;
-
- if (MI->isImplicitDef()) {
- DupCopies.push_back(MI);
- return true;
- } else {
- if (!MI->isFullCopy())
- return false;
- unsigned Src = MI->getOperand(1).getReg();
- if (!TargetRegisterInfo::isVirtualRegister(Src))
- return false;
- if (!OtherMI->isFullCopy())
- return false;
- unsigned OtherSrc = OtherMI->getOperand(1).getReg();
- if (!TargetRegisterInfo::isVirtualRegister(OtherSrc))
- return false;
-
- if (Src != OtherSrc)
- return false;
-
- // If the copies use two different value numbers of X, we cannot merge
- // A and B.
- LiveInterval &SrcInt = li.getInterval(Src);
- // getVNInfoBefore returns NULL for undef copies. In this case, the
- // optimization is still safe.
- if (SrcInt.getVNInfoBefore(OtherVNI->def) !=
- SrcInt.getVNInfoBefore(VNI->def))
- return false;
-
- DupCopies.push_back(MI);
- return true;
- }
-}
-
/// joinIntervals - Attempt to join these two intervals. On failure, this
/// returns false.
bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {
- // Handle physreg joins separately.
- if (CP.isPhys())
- return joinReservedPhysReg(CP);
-
- if (NewCoalescer)
- return joinVirtRegs(CP);
-
- LiveInterval &RHS = LIS->getInterval(CP.getSrcReg());
- DEBUG(dbgs() << "\t\tRHS = " << PrintReg(CP.getSrcReg()) << ' ' << RHS
- << '\n');
-
- // Compute the final value assignment, assuming that the live ranges can be
- // coalesced.
- SmallVector<int, 16> LHSValNoAssignments;
- SmallVector<int, 16> RHSValNoAssignments;
- DenseMap<VNInfo*, VNInfo*> LHSValsDefinedFromRHS;
- DenseMap<VNInfo*, VNInfo*> RHSValsDefinedFromLHS;
- SmallVector<VNInfo*, 16> NewVNInfo;
-
- SmallVector<MachineInstr*, 8> DupCopies;
- SmallVector<MachineInstr*, 8> DeadCopies;
-
- LiveInterval &LHS = LIS->getOrCreateInterval(CP.getDstReg());
- DEBUG(dbgs() << "\t\tLHS = " << PrintReg(CP.getDstReg(), TRI) << ' ' << LHS
- << '\n');
-
- // Loop over the value numbers of the LHS, seeing if any are defined from
- // the RHS.
- for (LiveInterval::vni_iterator i = LHS.vni_begin(), e = LHS.vni_end();
- i != e; ++i) {
- VNInfo *VNI = *i;
- if (VNI->isUnused() || VNI->isPHIDef())
- continue;
- MachineInstr *MI = LIS->getInstructionFromIndex(VNI->def);
- assert(MI && "Missing def");
- if (!MI->isCopyLike() && !MI->isImplicitDef()) // Src not defined by a copy?
- continue;
-
- // Figure out the value # from the RHS.
- VNInfo *OtherVNI = RHS.getVNInfoBefore(VNI->def);
- // The copy could be to an aliased physreg.
- if (!OtherVNI)
- continue;
-
- // DstReg is known to be a register in the LHS interval. If the src is
- // from the RHS interval, we can use its value #.
- if (CP.isCoalescable(MI))
- DeadCopies.push_back(MI);
- else if (!RegistersDefinedFromSameValue(*LIS, *TRI, CP, VNI, OtherVNI,
- DupCopies))
- continue;
-
- LHSValsDefinedFromRHS[VNI] = OtherVNI;
- }
-
- // Loop over the value numbers of the RHS, seeing if any are defined from
- // the LHS.
- for (LiveInterval::vni_iterator i = RHS.vni_begin(), e = RHS.vni_end();
- i != e; ++i) {
- VNInfo *VNI = *i;
- if (VNI->isUnused() || VNI->isPHIDef())
- continue;
- MachineInstr *MI = LIS->getInstructionFromIndex(VNI->def);
- assert(MI && "Missing def");
- if (!MI->isCopyLike() && !MI->isImplicitDef()) // Src not defined by a copy?
- continue;
-
- // Figure out the value # from the LHS.
- VNInfo *OtherVNI = LHS.getVNInfoBefore(VNI->def);
- // The copy could be to an aliased physreg.
- if (!OtherVNI)
- continue;
-
- // DstReg is known to be a register in the RHS interval. If the src is
- // from the LHS interval, we can use its value #.
- if (CP.isCoalescable(MI))
- DeadCopies.push_back(MI);
- else if (!RegistersDefinedFromSameValue(*LIS, *TRI, CP, VNI, OtherVNI,
- DupCopies))
- continue;
-
- RHSValsDefinedFromLHS[VNI] = OtherVNI;
- }
-
- LHSValNoAssignments.resize(LHS.getNumValNums(), -1);
- RHSValNoAssignments.resize(RHS.getNumValNums(), -1);
- NewVNInfo.reserve(LHS.getNumValNums() + RHS.getNumValNums());
-
- for (LiveInterval::vni_iterator i = LHS.vni_begin(), e = LHS.vni_end();
- i != e; ++i) {
- VNInfo *VNI = *i;
- unsigned VN = VNI->id;
- if (LHSValNoAssignments[VN] >= 0 || VNI->isUnused())
- continue;
- ComputeUltimateVN(VNI, NewVNInfo,
- LHSValsDefinedFromRHS, RHSValsDefinedFromLHS,
- LHSValNoAssignments, RHSValNoAssignments);
- }
- for (LiveInterval::vni_iterator i = RHS.vni_begin(), e = RHS.vni_end();
- i != e; ++i) {
- VNInfo *VNI = *i;
- unsigned VN = VNI->id;
- if (RHSValNoAssignments[VN] >= 0 || VNI->isUnused())
- continue;
- // If this value number isn't a copy from the LHS, it's a new number.
- if (RHSValsDefinedFromLHS.find(VNI) == RHSValsDefinedFromLHS.end()) {
- NewVNInfo.push_back(VNI);
- RHSValNoAssignments[VN] = NewVNInfo.size()-1;
- continue;
- }
-
- ComputeUltimateVN(VNI, NewVNInfo,
- RHSValsDefinedFromLHS, LHSValsDefinedFromRHS,
- RHSValNoAssignments, LHSValNoAssignments);
- }
-
- // Armed with the mappings of LHS/RHS values to ultimate values, walk the
- // interval lists to see if these intervals are coalescable.
- LiveInterval::const_iterator I = LHS.begin();
- LiveInterval::const_iterator IE = LHS.end();
- LiveInterval::const_iterator J = RHS.begin();
- LiveInterval::const_iterator JE = RHS.end();
-
- // Collect interval end points that will no longer be kills.
- SmallVector<MachineInstr*, 8> LHSOldKills;
- SmallVector<MachineInstr*, 8> RHSOldKills;
-
- // Skip ahead until the first place of potential sharing.
- if (I != IE && J != JE) {
- if (I->start < J->start) {
- I = std::upper_bound(I, IE, J->start);
- if (I != LHS.begin()) --I;
- } else if (J->start < I->start) {
- J = std::upper_bound(J, JE, I->start);
- if (J != RHS.begin()) --J;
- }
- }
-
- while (I != IE && J != JE) {
- // Determine if these two live ranges overlap.
- // If so, check value # info to determine if they are really different.
- if (I->end > J->start && J->end > I->start) {
- // If the live range overlap will map to the same value number in the
- // result liverange, we can still coalesce them. If not, we can't.
- if (LHSValNoAssignments[I->valno->id] !=
- RHSValNoAssignments[J->valno->id])
- return false;
-
- // Extended live ranges should no longer be killed.
- if (!I->end.isBlock() && I->end < J->end)
- if (MachineInstr *MI = LIS->getInstructionFromIndex(I->end))
- LHSOldKills.push_back(MI);
- if (!J->end.isBlock() && J->end < I->end)
- if (MachineInstr *MI = LIS->getInstructionFromIndex(J->end))
- RHSOldKills.push_back(MI);
- }
-
- if (I->end < J->end)
- ++I;
- else
- ++J;
- }
-
- // Clear kill flags where live ranges are extended.
- while (!LHSOldKills.empty())
- LHSOldKills.pop_back_val()->clearRegisterKills(LHS.reg, TRI);
- while (!RHSOldKills.empty())
- RHSOldKills.pop_back_val()->clearRegisterKills(RHS.reg, TRI);
-
- if (LHSValNoAssignments.empty())
- LHSValNoAssignments.push_back(-1);
- if (RHSValNoAssignments.empty())
- RHSValNoAssignments.push_back(-1);
-
- // Now erase all the redundant copies.
- for (unsigned i = 0, e = DeadCopies.size(); i != e; ++i) {
- MachineInstr *MI = DeadCopies[i];
- if (!ErasedInstrs.insert(MI))
- continue;
- DEBUG(dbgs() << "\t\terased:\t" << LIS->getInstructionIndex(MI)
- << '\t' << *MI);
- LIS->RemoveMachineInstrFromMaps(MI);
- MI->eraseFromParent();
- }
-
- SmallVector<unsigned, 8> SourceRegisters;
- for (SmallVector<MachineInstr*, 8>::iterator I = DupCopies.begin(),
- E = DupCopies.end(); I != E; ++I) {
- MachineInstr *MI = *I;
- if (!ErasedInstrs.insert(MI))
- continue;
-
- // If MI is a copy, then we have pretended that the assignment to B in
- // A = X
- // B = X
- // was actually a copy from A. Now that we decided to coalesce A and B,
- // transform the code into
- // A = X
- // In the case of the implicit_def, we just have to remove it.
- if (!MI->isImplicitDef()) {
- unsigned Src = MI->getOperand(1).getReg();
- SourceRegisters.push_back(Src);
- }
- LIS->RemoveMachineInstrFromMaps(MI);
- MI->eraseFromParent();
- }
-
- // If B = X was the last use of X in a liverange, we have to shrink it now
- // that B = X is gone.
- for (SmallVector<unsigned, 8>::iterator I = SourceRegisters.begin(),
- E = SourceRegisters.end(); I != E; ++I) {
- LIS->shrinkToUses(&LIS->getInterval(*I));
- }
-
- // If we get here, we know that we can coalesce the live ranges. Ask the
- // intervals to coalesce themselves now.
- LHS.join(RHS, &LHSValNoAssignments[0], &RHSValNoAssignments[0], NewVNInfo,
- MRI);
- return true;
+ return CP.isPhys() ? joinReservedPhysReg(CP) : joinVirtRegs(CP);
}
namespace {
diff --git a/lib/CodeGen/ScheduleDAGInstrs.cpp b/lib/CodeGen/ScheduleDAGInstrs.cpp
index a1a4efd108..ad0bad22aa 100644
--- a/lib/CodeGen/ScheduleDAGInstrs.cpp
+++ b/lib/CodeGen/ScheduleDAGInstrs.cpp
@@ -46,8 +46,8 @@ ScheduleDAGInstrs::ScheduleDAGInstrs(MachineFunction &mf,
LiveIntervals *lis)
: ScheduleDAG(mf), MLI(mli), MDT(mdt), MFI(mf.getFrameInfo()),
InstrItins(mf.getTarget().getInstrItineraryData()), LIS(lis),
- IsPostRA(IsPostRAFlag), UnitLatencies(false), CanHandleTerminators(false),
- LoopRegs(MDT), FirstDbgValue(0) {
+ IsPostRA(IsPostRAFlag), CanHandleTerminators(false), LoopRegs(MDT),
+ FirstDbgValue(0) {
assert((IsPostRA || LIS) && "PreRA scheduling requires LiveIntervals");
DbgValues.clear();
assert(!(IsPostRA && MRI.getNumVirtRegs()) &&
@@ -177,9 +177,6 @@ void ScheduleDAGInstrs::enterRegion(MachineBasicBlock *bb,
EndIndex = endcount;
MISUnitMap.clear();
- // Check to see if the scheduler cares about latencies.
- UnitLatencies = forceUnitLatencies();
-
ScheduleDAG::clearDAG();
}
@@ -241,8 +238,6 @@ void ScheduleDAGInstrs::addPhysRegDataDeps(SUnit *SU, unsigned OperIdx) {
// Ask the target if address-backscheduling is desirable, and if so how much.
const TargetSubtargetInfo &ST = TM.getSubtarget<TargetSubtargetInfo>();
- unsigned SpecialAddressLatency = ST.getSpecialAddressLatency();
- unsigned DataLatency = SU->Latency;
for (MCRegAliasIterator Alias(MO.getReg(), TRI, true);
Alias.isValid(); ++Alias) {
@@ -253,40 +248,21 @@ void ScheduleDAGInstrs::addPhysRegDataDeps(SUnit *SU, unsigned OperIdx) {
SUnit *UseSU = UseList[i].SU;
if (UseSU == SU)
continue;
- MachineInstr *UseMI = UseSU->getInstr();
+
+ SDep dep(SU, SDep::Data, 1, *Alias);
+
+ // Adjust the dependence latency using operand def/use information,
+ // then allow the target to perform its own adjustments.
int UseOp = UseList[i].OpIdx;
- unsigned LDataLatency = DataLatency;
- // Optionally add in a special extra latency for nodes that
- // feed addresses.
- // TODO: Perhaps we should get rid of
- // SpecialAddressLatency and just move this into
- // adjustSchedDependency for the targets that care about it.
- if (SpecialAddressLatency != 0 && !UnitLatencies &&
- UseSU != &ExitSU) {
- const MCInstrDesc &UseMCID = UseMI->getDesc();
- int RegUseIndex = UseMI->findRegisterUseOperandIdx(*Alias);
- assert(RegUseIndex >= 0 && "UseMI doesn't use register!");
- if (RegUseIndex >= 0 &&
- (UseMI->mayLoad() || UseMI->mayStore()) &&
- (unsigned)RegUseIndex < UseMCID.getNumOperands() &&
- UseMCID.OpInfo[RegUseIndex].isLookupPtrRegClass())
- LDataLatency += SpecialAddressLatency;
- }
- // Adjust the dependence latency using operand def/use
- // information (if any), and then allow the target to
- // perform its own adjustments.
- SDep dep(SU, SDep::Data, LDataLatency, *Alias);
- if (!UnitLatencies) {
- MachineInstr *RegUse = UseOp < 0 ? 0 : UseMI;
- dep.setLatency(
- SchedModel.computeOperandLatency(SU->getInstr(), OperIdx,
- RegUse, UseOp, /*FindMin=*/false));
- dep.setMinLatency(
- SchedModel.computeOperandLatency(SU->getInstr(), OperIdx,
- RegUse, UseOp, /*FindMin=*/true));
-
- ST.adjustSchedDependency(SU, UseSU, dep);
- }
+ MachineInstr *RegUse = UseOp < 0 ? 0 : UseSU->getInstr();
+ dep.setLatency(
+ SchedModel.computeOperandLatency(SU->getInstr(), OperIdx,
+ RegUse, UseOp, /*FindMin=*/false));
+ dep.setMinLatency(
+ SchedModel.computeOperandLatency(SU->getInstr(), OperIdx,
+ RegUse, UseOp, /*FindMin=*/true));
+
+ ST.adjustSchedDependency(SU, UseSU, dep);
UseSU->addPred(dep);
}
}
@@ -344,7 +320,7 @@ void ScheduleDAGInstrs::addPhysRegDeps(SUnit *SU, unsigned OperIdx) {
// If a def is going to wrap back around to the top of the loop,
// backschedule it.
- if (!UnitLatencies && DefList.empty()) {
+ if (DefList.empty()) {
LoopDependencies::LoopDeps::iterator I = LoopRegs.Deps.find(MO.getReg());
if (I != LoopRegs.Deps.end()) {
const MachineOperand *UseMO = I->second.first;
@@ -352,9 +328,6 @@ void ScheduleDAGInstrs::addPhysRegDeps(SUnit *SU, unsigned OperIdx) {
const MachineInstr *UseMI = UseMO->getParent();
unsigned UseMOIdx = UseMO - &UseMI->getOperand(0);
const MCInstrDesc &UseMCID = UseMI->getDesc();
- const TargetSubtargetInfo &ST =
- TM.getSubtarget<TargetSubtargetInfo>();
- unsigned SpecialAddressLatency = ST.getSpecialAddressLatency();
// TODO: If we knew the total depth of the region here, we could
// handle the case where the whole loop is inside the region but
// is large enough that the isScheduleHigh trick isn't needed.
@@ -364,8 +337,6 @@ void ScheduleDAGInstrs::addPhysRegDeps(SUnit *SU, unsigned OperIdx) {
// the same region by checking to see if it has the same parent.
if (UseMI->getParent() != MI->getParent()) {
unsigned Latency = SU->Latency;
- if (UseMCID.OpInfo[UseMOIdx].isLookupPtrRegClass())
- Latency += SpecialAddressLatency;
// This is a wild guess as to the portion of the latency which
// will be overlapped by work done outside the current
// scheduling region.
@@ -375,14 +346,6 @@ void ScheduleDAGInstrs::addPhysRegDeps(SUnit *SU, unsigned OperIdx) {
/*Reg=*/0, /*isNormalMemory=*/false,
/*isMustAlias=*/false,
/*isArtificial=*/true));
- } else if (SpecialAddressLatency > 0 &&
- UseMCID.OpInfo[UseMOIdx].isLookupPtrRegClass()) {
- // The entire loop body is within the current scheduling region
- // and the latency of this operation is assumed to be greater
- // than the latency of the loop.
- // TODO: Recursively mark data-edge predecessors as
- // isScheduleHigh too.
- SU->isScheduleHigh = true;
}
}
LoopRegs.Deps.erase(I);
@@ -471,21 +434,17 @@ void ScheduleDAGInstrs::addVRegUseDeps(SUnit *SU, unsigned OperIdx) {
if (DefSU) {
// The reaching Def lives within this scheduling region.
// Create a data dependence.
- //
- // TODO: Handle "special" address latencies cleanly.
- SDep dep(DefSU, SDep::Data, DefSU->Latency, Reg);
- if (!UnitLatencies) {
- // Adjust the dependence latency using operand def/use information, then
- // allow the target to perform its own adjustments.
- int DefOp = Def->findRegisterDefOperandIdx(Reg);
- dep.setLatency(
- SchedModel.computeOperandLatency(Def, DefOp, MI, OperIdx, false));
- dep.setMinLatency(
- SchedModel.computeOperandLatency(Def, DefOp, MI, OperIdx, true));
-
- const TargetSubtargetInfo &ST = TM.getSubtarget<TargetSubtargetInfo>();
- ST.adjustSchedDependency(DefSU, SU, const_cast<SDep &>(dep));
- }
+ SDep dep(DefSU, SDep::Data, 1, Reg);
+ // Adjust the dependence latency using operand def/use information, then
+ // allow the target to perform its own adjustments.
+ int DefOp = Def->findRegisterDefOperandIdx(Reg);
+ dep.setLatency(
+ SchedModel.computeOperandLatency(Def, DefOp, MI, OperIdx, false));
+ dep.setMinLatency(
+ SchedModel.computeOperandLatency(Def, DefOp, MI, OperIdx, true));
+
+ const TargetSubtargetInfo &ST = TM.getSubtarget<TargetSubtargetInfo>();
+ ST.adjustSchedDependency(DefSU, SU, const_cast<SDep &>(dep));
SU->addPred(dep);
}
}
@@ -730,10 +689,7 @@ void ScheduleDAGInstrs::initSUnits() {
SU->isCommutable = MI->isCommutable();
// Assign the Latency field of SU using target-provided information.
- if (UnitLatencies)
- SU->Latency = 1;
- else
- computeLatency(SU);
+ computeLatency(SU);
}
}
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index d115991858..e572de5c24 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -23,7 +23,7 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
@@ -301,6 +301,11 @@ namespace {
/// looking for a better chain (aliasing node.)
SDValue FindBetterChain(SDNode *N, SDValue Chain);
+ /// Merge consecutive store operations into a wide store.
+ /// This optimization uses wide integers or vectors when possible.
+ /// \return True if some memory operations were changed.
+ bool MergeConsecutiveStores(StoreSDNode *N);
+
public:
DAGCombiner(SelectionDAG &D, AliasAnalysis &A, CodeGenOpt::Level OL)
: DAG(D), TLI(D.getTargetLoweringInfo()), Level(BeforeLegalizeTypes),
@@ -5340,7 +5345,7 @@ SDValue DAGCombiner::CombineConsecutiveLoads(SDNode *N, EVT VT) {
!LD2->isVolatile() &&
DAG.isConsecutiveLoad(LD2, LD1, LD1VT.getSizeInBits()/8, 1)) {
unsigned Align = LD1->getAlignment();
- unsigned NewAlign = TLI.getTargetData()->
+ unsigned NewAlign = TLI.getDataLayout()->
getABITypeAlignment(VT.getTypeForEVT(*DAG.getContext()));
if (NewAlign <= Align &&
@@ -5409,7 +5414,7 @@ SDValue DAGCombiner::visitBITCAST(SDNode *N) {
!cast<LoadSDNode>(N0)->isVolatile() &&
(!LegalOperations || TLI.isOperationLegal(ISD::LOAD, VT))) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0);
- unsigned Align = TLI.getTargetData()->
+ unsigned Align = TLI.getDataLayout()->
getABITypeAlignment(VT.getTypeForEVT(*DAG.getContext()));
unsigned OrigAlign = LN0->getAlignment();
@@ -6709,7 +6714,7 @@ static bool canFoldInAddressingMode(SDNode *N, SDNode *Use,
} else
return false;
- TargetLowering::AddrMode AM;
+ AddrMode AM;
if (N->getOpcode() == ISD::ADD) {
ConstantSDNode *Offset = dyn_cast<ConstantSDNode>(N->getOperand(1));
if (Offset)
@@ -7336,7 +7341,7 @@ SDValue DAGCombiner::ReduceLoadOpStoreWidth(SDNode *N) {
unsigned NewAlign = MinAlign(LD->getAlignment(), PtrOff);
Type *NewVTTy = NewVT.getTypeForEVT(*DAG.getContext());
- if (NewAlign < TLI.getTargetData()->getABITypeAlignment(NewVTTy))
+ if (NewAlign < TLI.getDataLayout()->getABITypeAlignment(NewVTTy))
return SDValue();
SDValue NewPtr = DAG.getNode(ISD::ADD, LD->getDebugLoc(),
@@ -7398,7 +7403,7 @@ SDValue DAGCombiner::TransformFPLoadStorePair(SDNode *N) {
unsigned LDAlign = LD->getAlignment();
unsigned STAlign = ST->getAlignment();
Type *IntVTTy = IntVT.getTypeForEVT(*DAG.getContext());
- unsigned ABIAlign = TLI.getTargetData()->getABITypeAlignment(IntVTTy);
+ unsigned ABIAlign = TLI.getDataLayout()->getABITypeAlignment(IntVTTy);
if (LDAlign < ABIAlign || STAlign < ABIAlign)
return SDValue();
@@ -7423,6 +7428,422 @@ SDValue DAGCombiner::TransformFPLoadStorePair(SDNode *N) {
return SDValue();
}
+/// Returns the base pointer and an integer offset from that object.
+static std::pair<SDValue, int64_t> GetPointerBaseAndOffset(SDValue Ptr) {
+ if (Ptr->getOpcode() == ISD::ADD && isa<ConstantSDNode>(Ptr->getOperand(1))) {
+ int64_t Offset = cast<ConstantSDNode>(Ptr->getOperand(1))->getSExtValue();
+ SDValue Base = Ptr->getOperand(0);
+ return std::make_pair(Base, Offset);
+ }
+
+ return std::make_pair(Ptr, 0);
+}
+
+/// Holds a pointer to an LSBaseSDNode as well as information on where it
+/// is located in a sequence of memory operations connected by a chain.
+struct MemOpLink {
+ MemOpLink (LSBaseSDNode *N, int64_t Offset, unsigned Seq):
+ MemNode(N), OffsetFromBase(Offset), SequenceNum(Seq) { }
+ // Ptr to the mem node.
+ LSBaseSDNode *MemNode;
+ // Offset from the base ptr.
+ int64_t OffsetFromBase;
+ // What is the sequence number of this mem node.
+ // Lowest mem operand in the DAG starts at zero.
+ unsigned SequenceNum;
+};
+
+/// Sorts store nodes in a link according to their offset from a shared
+// base ptr.
+struct ConsecutiveMemoryChainSorter {
+ bool operator()(MemOpLink LHS, MemOpLink RHS) {
+ return LHS.OffsetFromBase < RHS.OffsetFromBase;
+ }
+};
+
+bool DAGCombiner::MergeConsecutiveStores(StoreSDNode* St) {
+ EVT MemVT = St->getMemoryVT();
+ int64_t ElementSizeBytes = MemVT.getSizeInBits()/8;
+
+ // Don't merge vectors into wider inputs.
+ if (MemVT.isVector() || !MemVT.isSimple())
+ return false;
+
+ // Perform an early exit check. Do not bother looking at stored values that
+ // are not constants or loads.
+ SDValue StoredVal = St->getValue();
+ bool IsLoadSrc = isa<LoadSDNode>(StoredVal);
+ if (!isa<ConstantSDNode>(StoredVal) && !isa<ConstantFPSDNode>(StoredVal) &&
+ !IsLoadSrc)
+ return false;
+
+ // Only look at ends of store sequences.
+ SDValue Chain = SDValue(St, 1);
+ if (Chain->hasOneUse() && Chain->use_begin()->getOpcode() == ISD::STORE)
+ return false;
+
+ // This holds the base pointer and the offset in bytes from the base pointer.
+ std::pair<SDValue, int64_t> BasePtr =
+ GetPointerBaseAndOffset(St->getBasePtr());
+
+ // We must have a base and an offset.
+ if (!BasePtr.first.getNode())
+ return false;
+
+ // Do not handle stores to undef base pointers.
+ if (BasePtr.first.getOpcode() == ISD::UNDEF)
+ return false;
+
+ SmallVector<MemOpLink, 8> StoreNodes;
+ // Walk up the chain and look for nodes with offsets from the same
+ // base pointer. Stop when reaching an instruction with a different kind
+ // or instruction which has a different base pointer.
+ unsigned Seq = 0;
+ StoreSDNode *Index = St;
+ while (Index) {
+ // If the chain has more than one use, then we can't reorder the mem ops.
+ if (Index != St && !SDValue(Index, 1)->hasOneUse())
+ break;
+
+ // Find the base pointer and offset for this memory node.
+ std::pair<SDValue, int64_t> Ptr =
+ GetPointerBaseAndOffset(Index->getBasePtr());
+
+ // Check that the base pointer is the same as the original one.
+ if (Ptr.first.getNode() != BasePtr.first.getNode())
+ break;
+
+ // Check that the alignment is the same.
+ if (Index->getAlignment() != St->getAlignment())
+ break;
+
+ // The memory operands must not be volatile.
+ if (Index->isVolatile() || Index->isIndexed())
+ break;
+
+ // No truncation.
+ if (StoreSDNode *St = dyn_cast<StoreSDNode>(Index))
+ if (St->isTruncatingStore())
+ break;
+
+ // The stored memory type must be the same.
+ if (Index->getMemoryVT() != MemVT)
+ break;
+
+ // We do not allow unaligned stores because we want to prevent overriding
+ // stores.
+ if (Index->getAlignment()*8 != MemVT.getSizeInBits())
+ break;
+
+ // We found a potential memory operand to merge.
+ StoreNodes.push_back(MemOpLink(Index, Ptr.second, Seq++));
+
+ // Move up the chain to the next memory operation.
+ Index = dyn_cast<StoreSDNode>(Index->getChain().getNode());
+ }
+
+ // Check if there is anything to merge.
+ if (StoreNodes.size() < 2)
+ return false;
+
+ // Sort the memory operands according to their distance from the base pointer.
+ std::sort(StoreNodes.begin(), StoreNodes.end(),
+ ConsecutiveMemoryChainSorter());
+
+ // Scan the memory operations on the chain and find the first non-consecutive
+ // store memory address.
+ unsigned LastConsecutiveStore = 0;
+ int64_t StartAddress = StoreNodes[0].OffsetFromBase;
+ for (unsigned i=1; i<StoreNodes.size(); ++i) {
+ int64_t CurrAddress = StoreNodes[i].OffsetFromBase;
+ if (CurrAddress - StartAddress != (ElementSizeBytes * i))
+ break;
+
+ // Mark this node as useful.
+ LastConsecutiveStore = i;
+ }
+
+ // The node with the lowest store address.
+ LSBaseSDNode *FirstInChain = StoreNodes[0].MemNode;
+
+ // Store the constants into memory as one consecutive store.
+ if (!IsLoadSrc) {
+ unsigned LastLegalType = 0;
+ unsigned LastLegalVectorType = 0;
+ bool NonZero = false;
+ for (unsigned i=0; i<LastConsecutiveStore+1; ++i) {
+ StoreSDNode *St = cast<StoreSDNode>(StoreNodes[i].MemNode);
+ SDValue StoredVal = St->getValue();
+
+ if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(StoredVal)) {
+ NonZero |= !C->isNullValue();
+ } else if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(StoredVal)) {
+ NonZero |= !C->getConstantFPValue()->isNullValue();
+ } else {
+ // Non constant.
+ break;
+ }
+
+ // Find a legal type for the constant store.
+ unsigned StoreBW = (i+1) * ElementSizeBytes * 8;
+ EVT StoreTy = EVT::getIntegerVT(*DAG.getContext(), StoreBW);
+ if (TLI.isTypeLegal(StoreTy))
+ LastLegalType = i+1;
+
+ // Find a legal type for the vector store.
+ EVT Ty = EVT::getVectorVT(*DAG.getContext(), MemVT, i+1);
+ if (TLI.isTypeLegal(Ty))
+ LastLegalVectorType = i + 1;
+ }
+
+ // We only use vectors if the constant is known to be zero.
+ if (NonZero)
+ LastLegalVectorType = 0;
+
+ // Check if we found a legal integer type to store.
+ if (LastLegalType == 0 && LastLegalVectorType == 0)
+ return false;
+
+ bool UseVector = LastLegalVectorType > LastLegalType;
+ unsigned NumElem = UseVector ? LastLegalVectorType : LastLegalType;
+
+ // Make sure we have something to merge.
+ if (NumElem < 2)
+ return false;
+
+ unsigned EarliestNodeUsed = 0;
+ for (unsigned i=0; i < NumElem; ++i) {
+ // Find a chain for the new wide-store operand. Notice that some
+ // of the store nodes that we found may not be selected for inclusion
+ // in the wide store. The chain we use needs to be the chain of the
+ // earliest store node which is *used* and replaced by the wide store.
+ if (StoreNodes[i].SequenceNum > StoreNodes[EarliestNodeUsed].SequenceNum)
+ EarliestNodeUsed = i;
+ }
+
+ // The earliest Node in the DAG.
+ LSBaseSDNode *EarliestOp = StoreNodes[EarliestNodeUsed].MemNode;
+ DebugLoc DL = StoreNodes[0].MemNode->getDebugLoc();
+
+ SDValue StoredVal;
+ if (UseVector) {
+ // Find a legal type for the vector store.
+ EVT Ty = EVT::getVectorVT(*DAG.getContext(), MemVT, NumElem);
+ assert(TLI.isTypeLegal(Ty) && "Illegal vector store");
+ StoredVal = DAG.getConstant(0, Ty);
+ } else {
+ unsigned StoreBW = NumElem * ElementSizeBytes * 8;
+ APInt StoreInt(StoreBW, 0);
+
+ // Construct a single integer constant which is made of the smaller
+ // constant inputs.
+ bool IsLE = TLI.isLittleEndian();
+ for (unsigned i = 0; i < NumElem ; ++i) {
+ unsigned Idx = IsLE ?(NumElem - 1 - i) : i;
+ StoreSDNode *St = cast<StoreSDNode>(StoreNodes[Idx].MemNode);
+ SDValue Val = St->getValue();
+ StoreInt<<=ElementSizeBytes*8;
+ if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Val)) {
+ StoreInt|=C->getAPIntValue().zext(StoreBW);
+ } else if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Val)) {
+ StoreInt|= C->getValueAPF().bitcastToAPInt().zext(StoreBW);
+ } else {
+ assert(false && "Invalid constant element type");
+ }
+ }
+
+ // Create the new Load and Store operations.
+ EVT StoreTy = EVT::getIntegerVT(*DAG.getContext(), StoreBW);
+ StoredVal = DAG.getConstant(StoreInt, StoreTy);
+ }
+
+ SDValue NewStore = DAG.getStore(EarliestOp->getChain(), DL, StoredVal,
+ FirstInChain->getBasePtr(),
+ FirstInChain->getPointerInfo(),
+ false, false,
+ FirstInChain->getAlignment());
+
+ // Replace the first store with the new store
+ CombineTo(EarliestOp, NewStore);
+ // Erase all other stores.
+ for (unsigned i = 0; i < NumElem ; ++i) {
+ if (StoreNodes[i].MemNode == EarliestOp)
+ continue;
+ StoreSDNode *St = cast<StoreSDNode>(StoreNodes[i].MemNode);
+ DAG.ReplaceAllUsesOfValueWith(SDValue(St, 0), St->getChain());
+ removeFromWorkList(St);
+ DAG.DeleteNode(St);
+ }
+
+ return true;
+ }
+
+ // Below we handle the case of multiple consecutive stores that
+ // come from multiple consecutive loads. We merge them into a single
+ // wide load and a single wide store.
+
+ // Look for load nodes which are used by the stored values.
+ SmallVector<MemOpLink, 8> LoadNodes;
+
+ // Find acceptable loads. Loads need to have the same chain (token factor),
+ // must not be zext, volatile, indexed, and they must be consecutive.
+ SDValue LdBasePtr;
+ for (unsigned i=0; i<LastConsecutiveStore+1; ++i) {
+ StoreSDNode *St = cast<StoreSDNode>(StoreNodes[i].MemNode);
+ LoadSDNode *Ld = dyn_cast<LoadSDNode>(St->getValue());
+ if (!Ld) break;
+
+ // Loads must only have one use.
+ if (!Ld->hasNUsesOfValue(1, 0))
+ break;
+
+ // Check that the alignment is the same as the stores.
+ if (Ld->getAlignment() != St->getAlignment())
+ break;
+
+ // The memory operands must not be volatile.
+ if (Ld->isVolatile() || Ld->isIndexed())
+ break;
+
+ // We do not accept ext loads.
+ if (Ld->getExtensionType() != ISD::NON_EXTLOAD)
+ break;
+
+ // The stored memory type must be the same.
+ if (Ld->getMemoryVT() != MemVT)
+ break;
+
+ std::pair<SDValue, int64_t> LdPtr =
+ GetPointerBaseAndOffset(Ld->getBasePtr());
+
+ // If this is not the first ptr that we check.
+ if (LdBasePtr.getNode()) {
+ // The base ptr must be the same.
+ if (LdPtr.first != LdBasePtr)
+ break;
+ } else {
+ // Check that all other base pointers are the same as this one.
+ LdBasePtr = LdPtr.first;
+ }
+
+ // We found a potential memory operand to merge.
+ LoadNodes.push_back(MemOpLink(Ld, LdPtr.second, 0));
+ }
+
+ if (LoadNodes.size() < 2)
+ return false;
+
+ // Scan the memory operations on the chain and find the first non-consecutive
+ // load memory address. These variables hold the index in the store node
+ // array.
+ unsigned LastConsecutiveLoad = 0;
+ // This variable refers to the size and not index in the array.
+ unsigned LastLegalVectorType = 0;
+ unsigned LastLegalIntegerType = 0;
+ StartAddress = LoadNodes[0].OffsetFromBase;
+ SDValue FirstChain = LoadNodes[0].MemNode->getChain();
+ for (unsigned i = 1; i < LoadNodes.size(); ++i) {
+ // All loads much share the same chain.
+ if (LoadNodes[i].MemNode->getChain() != FirstChain)
+ break;
+
+ int64_t CurrAddress = LoadNodes[i].OffsetFromBase;
+ if (CurrAddress - StartAddress != (ElementSizeBytes * i))
+ break;
+ LastConsecutiveLoad = i;
+
+ // Find a legal type for the vector store.
+ EVT StoreTy = EVT::getVectorVT(*DAG.getContext(), MemVT, i+1);
+ if (TLI.isTypeLegal(StoreTy))
+ LastLegalVectorType = i + 1;
+
+ // Find a legal type for the integer store.
+ unsigned StoreBW = (i+1) * ElementSizeBytes * 8;
+ StoreTy = EVT::getIntegerVT(*DAG.getContext(), StoreBW);
+ if (TLI.isTypeLegal(StoreTy))
+ LastLegalIntegerType = i + 1;
+ }
+
+ // Only use vector types if the vector type is larger than the integer type.
+ // If they are the same, use integers.
+ bool UseVectorTy = LastLegalVectorType > LastLegalIntegerType;
+ unsigned LastLegalType = std::max(LastLegalVectorType, LastLegalIntegerType);
+
+ // We add +1 here because the LastXXX variables refer to location while
+ // the NumElem refers to array/index size.
+ unsigned NumElem = std::min(LastConsecutiveStore, LastConsecutiveLoad) + 1;
+ NumElem = std::min(LastLegalType, NumElem);
+
+ if (NumElem < 2)
+ return false;
+
+ // The earliest Node in the DAG.
+ unsigned EarliestNodeUsed = 0;
+ LSBaseSDNode *EarliestOp = StoreNodes[EarliestNodeUsed].MemNode;
+ for (unsigned i=1; i<NumElem; ++i) {
+ // Find a chain for the new wide-store operand. Notice that some
+ // of the store nodes that we found may not be selected for inclusion
+ // in the wide store. The chain we use needs to be the chain of the
+ // earliest store node which is *used* and replaced by the wide store.
+ if (StoreNodes[i].SequenceNum > StoreNodes[EarliestNodeUsed].SequenceNum)
+ EarliestNodeUsed = i;
+ }
+
+ // Find if it is better to use vectors or integers to load and store
+ // to memory.
+ EVT JointMemOpVT;
+ if (UseVectorTy) {
+ JointMemOpVT = EVT::getVectorVT(*DAG.getContext(), MemVT, NumElem);
+ } else {
+ unsigned StoreBW = NumElem * ElementSizeBytes * 8;
+ JointMemOpVT = EVT::getIntegerVT(*DAG.getContext(), StoreBW);
+ }
+
+ DebugLoc LoadDL = LoadNodes[0].MemNode->getDebugLoc();
+ DebugLoc StoreDL = StoreNodes[0].MemNode->getDebugLoc();
+
+ LoadSDNode *FirstLoad = cast<LoadSDNode>(LoadNodes[0].MemNode);
+ SDValue NewLoad = DAG.getLoad(JointMemOpVT, LoadDL,
+ FirstLoad->getChain(),
+ FirstLoad->getBasePtr(),
+ FirstLoad->getPointerInfo(),
+ false, false, false,
+ FirstLoad->getAlignment());
+
+ SDValue NewStore = DAG.getStore(EarliestOp->getChain(), StoreDL, NewLoad,
+ FirstInChain->getBasePtr(),
+ FirstInChain->getPointerInfo(), false, false,
+ FirstInChain->getAlignment());
+
+ // Replace one of the loads with the new load.
+ LoadSDNode *Ld = cast<LoadSDNode>(LoadNodes[0].MemNode);
+ DAG.ReplaceAllUsesOfValueWith(SDValue(Ld, 1),
+ SDValue(NewLoad.getNode(), 1));
+
+ // Remove the rest of the load chains.
+ for (unsigned i = 1; i < NumElem ; ++i) {
+ // Replace all chain users of the old load nodes with the chain of the new
+ // load node.
+ LoadSDNode *Ld = cast<LoadSDNode>(LoadNodes[i].MemNode);
+ DAG.ReplaceAllUsesOfValueWith(SDValue(Ld, 1), Ld->getChain());
+ }
+
+ // Replace the first store with the new store.
+ CombineTo(EarliestOp, NewStore);
+ // Erase all other stores.
+ for (unsigned i = 0; i < NumElem ; ++i) {
+ // Remove all Store nodes.
+ if (StoreNodes[i].MemNode == EarliestOp)
+ continue;
+ StoreSDNode *St = cast<StoreSDNode>(StoreNodes[i].MemNode);
+ DAG.ReplaceAllUsesOfValueWith(SDValue(St, 0), St->getChain());
+ removeFromWorkList(St);
+ DAG.DeleteNode(St);
+ }
+
+ return true;
+}
+
SDValue DAGCombiner::visitSTORE(SDNode *N) {
StoreSDNode *ST = cast<StoreSDNode>(N);
SDValue Chain = ST->getChain();
@@ -7435,7 +7856,7 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
ST->isUnindexed()) {
unsigned OrigAlign = ST->getAlignment();
EVT SVT = Value.getOperand(0).getValueType();
- unsigned Align = TLI.getTargetData()->
+ unsigned Align = TLI.getDataLayout()->
getABITypeAlignment(SVT.getTypeForEVT(*DAG.getContext()));
if (Align <= OrigAlign &&
((!LegalOperations && !ST->isVolatile()) ||
@@ -7624,6 +8045,11 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
ST->getAlignment());
}
+ // Only perform this optimization before the types are legal, because we
+ // don't want to perform this optimization on every DAGCombine invocation.
+ if (!LegalTypes && MergeConsecutiveStores(ST))
+ return SDValue(N, 0);
+
return ReduceLoadOpStoreWidth(N);
}
@@ -7823,7 +8249,7 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) {
// Check the resultant load doesn't need a higher alignment than the
// original load.
unsigned NewAlign =
- TLI.getTargetData()
+ TLI.getDataLayout()
->getABITypeAlignment(LVT.getTypeForEVT(*DAG.getContext()));
if (NewAlign > Align || !TLI.isOperationLegalOrCustom(ISD::LOAD, LVT))
@@ -8704,7 +9130,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1,
// @LOCALMOD-START
// when we combine two 8byte constants into a 16byte one
// we get constant pool entries which are too big
- TLI.getTargetData()->getTypeAllocSize(FV->getConstantFPValue()->getType()) <= 4 &&
+ TLI.getDataLayout()->getTypeAllocSize(FV->getConstantFPValue()->getType()) <= 4 &&
// @LOCALMOD-STOP
(TLI.getOperationAction(ISD::ConstantFP, N2.getValueType()) !=
TargetLowering::Legal) &&
@@ -8716,7 +9142,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1,
const_cast<ConstantFP*>(TV->getConstantFPValue())
};
Type *FPTy = Elts[0]->getType();
- const TargetData &TD = *TLI.getTargetData();
+ const DataLayout &TD = *TLI.getDataLayout();
// Create a ConstantArray of the two constants.
Constant *CA = ConstantArray::get(ArrayType::get(FPTy, 2), Elts);
diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp
index 683fac6744..4854cf7b26 100644
--- a/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -53,7 +53,7 @@
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Analysis/Loads.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Target/TargetLowering.h"
@@ -1059,7 +1059,7 @@ FastISel::FastISel(FunctionLoweringInfo &funcInfo,
MFI(*FuncInfo.MF->getFrameInfo()),
MCP(*FuncInfo.MF->getConstantPool()),
TM(FuncInfo.MF->getTarget()),
- TD(*TM.getTargetData()),
+ TD(*TM.getDataLayout()),
TII(*TM.getInstrInfo()),
TLI(*TM.getTargetLowering()),
TRI(*TM.getRegisterInfo()),
diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
index b2a2a5cb25..a4182906cb 100644
--- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
+++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
@@ -29,7 +29,7 @@
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetOptions.h"
@@ -80,9 +80,9 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf) {
if (const AllocaInst *AI = dyn_cast<AllocaInst>(I))
if (const ConstantInt *CUI = dyn_cast<ConstantInt>(AI->getArraySize())) {
Type *Ty = AI->getAllocatedType();
- uint64_t TySize = TLI.getTargetData()->getTypeAllocSize(Ty);
+ uint64_t TySize = TLI.getDataLayout()->getTypeAllocSize(Ty);
unsigned Align =
- std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty),
+ std::max((unsigned)TLI.getDataLayout()->getPrefTypeAlignment(Ty),
AI->getAlignment());
TySize *= CUI->getZExtValue(); // Get total allocated size.
diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index 5e631c2d8e..d1baa3f716 100644
--- a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -20,7 +20,7 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLowering.h"
@@ -390,10 +390,10 @@ void InstrEmitter::AddOperand(MachineInstr *MI, SDValue Op,
Type *Type = CP->getType();
// MachineConstantPool wants an explicit alignment.
if (Align == 0) {
- Align = TM->getTargetData()->getPrefTypeAlignment(Type);
+ Align = TM->getDataLayout()->getPrefTypeAlignment(Type);
if (Align == 0) {
// Alignment of vector types. FIXME!
- Align = TM->getTargetData()->getTypeAllocSize(Type);
+ Align = TM->getDataLayout()->getTypeAllocSize(Type);
}
}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 8b291e9a3c..80f495309d 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -22,7 +22,7 @@
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetLowering.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -718,7 +718,7 @@ void SelectionDAGLegalize::LegalizeStoreOps(SDNode *Node) {
// expand it.
if (!TLI.allowsUnalignedMemoryAccesses(ST->getMemoryVT())) {
Type *Ty = ST->getMemoryVT().getTypeForEVT(*DAG.getContext());
- unsigned ABIAlignment= TLI.getTargetData()->getABITypeAlignment(Ty);
+ unsigned ABIAlignment= TLI.getDataLayout()->getABITypeAlignment(Ty);
if (ST->getAlignment() < ABIAlignment)
ExpandUnalignedStore(cast<StoreSDNode>(Node),
DAG, TLI, this);
@@ -824,7 +824,7 @@ void SelectionDAGLegalize::LegalizeStoreOps(SDNode *Node) {
// expand it.
if (!TLI.allowsUnalignedMemoryAccesses(ST->getMemoryVT())) {
Type *Ty = ST->getMemoryVT().getTypeForEVT(*DAG.getContext());
- unsigned ABIAlignment= TLI.getTargetData()->getABITypeAlignment(Ty);
+ unsigned ABIAlignment= TLI.getDataLayout()->getABITypeAlignment(Ty);
if (ST->getAlignment() < ABIAlignment)
ExpandUnalignedStore(cast<StoreSDNode>(Node), DAG, TLI, this);
}
@@ -874,7 +874,7 @@ void SelectionDAGLegalize::LegalizeLoadOps(SDNode *Node) {
if (!TLI.allowsUnalignedMemoryAccesses(LD->getMemoryVT())) {
Type *Ty = LD->getMemoryVT().getTypeForEVT(*DAG.getContext());
unsigned ABIAlignment =
- TLI.getTargetData()->getABITypeAlignment(Ty);
+ TLI.getDataLayout()->getABITypeAlignment(Ty);
if (LD->getAlignment() < ABIAlignment){
ExpandUnalignedLoad(cast<LoadSDNode>(Node), DAG, TLI, RVal, RChain);
}
@@ -1059,7 +1059,7 @@ void SelectionDAGLegalize::LegalizeLoadOps(SDNode *Node) {
Type *Ty =
LD->getMemoryVT().getTypeForEVT(*DAG.getContext());
unsigned ABIAlignment =
- TLI.getTargetData()->getABITypeAlignment(Ty);
+ TLI.getDataLayout()->getABITypeAlignment(Ty);
if (LD->getAlignment() < ABIAlignment){
ExpandUnalignedLoad(cast<LoadSDNode>(Node),
DAG, TLI, Value, Chain);
@@ -1625,7 +1625,7 @@ SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp,
DebugLoc dl) {
// Create the stack frame object.
unsigned SrcAlign =
- TLI.getTargetData()->getPrefTypeAlignment(SrcOp.getValueType().
+ TLI.getDataLayout()->getPrefTypeAlignment(SrcOp.getValueType().
getTypeForEVT(*DAG.getContext()));
SDValue FIPtr = DAG.CreateStackTemporary(SlotVT, SrcAlign);
@@ -1637,7 +1637,7 @@ SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp,
unsigned SlotSize = SlotVT.getSizeInBits();
unsigned DestSize = DestVT.getSizeInBits();
Type *DestType = DestVT.getTypeForEVT(*DAG.getContext());
- unsigned DestAlign = TLI.getTargetData()->getPrefTypeAlignment(DestType);
+ unsigned DestAlign = TLI.getDataLayout()->getPrefTypeAlignment(DestType);
// Emit a store to the stack slot. Use a truncstore if the input value is
// later than DestVT.
@@ -2786,7 +2786,7 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
// Increment the pointer, VAList, to the next vaarg
Tmp3 = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), VAList,
- DAG.getConstant(TLI.getTargetData()->
+ DAG.getConstant(TLI.getDataLayout()->
getTypeAllocSize(VT.getTypeForEVT(*DAG.getContext())),
TLI.getPointerTy()));
// Store the incremented VAList to the legalized pointer
@@ -3365,7 +3365,7 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
EVT PTy = TLI.getPointerTy();
- const TargetData &TD = *TLI.getTargetData();
+ const DataLayout &TD = *TLI.getDataLayout();
unsigned EntrySize =
DAG.getMachineFunction().getJumpTableInfo()->getEntrySize(TD);
diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 1cccf1a057..a370faeb23 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -644,8 +644,9 @@ SDValue DAGTypeLegalizer::PromoteIntRes_XMULO(SDNode *N, unsigned ResNo) {
EVT SmallVT = LHS.getValueType();
// To determine if the result overflowed in a larger type, we extend the
- // input to the larger type, do the multiply, then check the high bits of
- // the result to see if the overflow happened.
+ // input to the larger type, do the multiply (checking if it overflows),
+ // then also check the high bits of the result to see if overflow happened
+ // there.
if (N->getOpcode() == ISD::SMULO) {
LHS = SExtPromotedInteger(LHS);
RHS = SExtPromotedInteger(RHS);
@@ -653,24 +654,31 @@ SDValue DAGTypeLegalizer::PromoteIntRes_XMULO(SDNode *N, unsigned ResNo) {
LHS = ZExtPromotedInteger(LHS);
RHS = ZExtPromotedInteger(RHS);
}
- SDValue Mul = DAG.getNode(ISD::MUL, DL, LHS.getValueType(), LHS, RHS);
+ SDVTList VTs = DAG.getVTList(LHS.getValueType(), N->getValueType(1));
+ SDValue Mul = DAG.getNode(N->getOpcode(), DL, VTs, LHS, RHS);
- // Overflow occurred iff the high part of the result does not
- // zero/sign-extend the low part.
+ // Overflow occurred if it occurred in the larger type, or if the high part
+ // of the result does not zero/sign-extend the low part. Check this second
+ // possibility first.
SDValue Overflow;
if (N->getOpcode() == ISD::UMULO) {
- // Unsigned overflow occurred iff the high part is non-zero.
+ // Unsigned overflow occurred if the high part is non-zero.
SDValue Hi = DAG.getNode(ISD::SRL, DL, Mul.getValueType(), Mul,
DAG.getIntPtrConstant(SmallVT.getSizeInBits()));
Overflow = DAG.getSetCC(DL, N->getValueType(1), Hi,
DAG.getConstant(0, Hi.getValueType()), ISD::SETNE);
} else {
- // Signed overflow occurred iff the high part does not sign extend the low.
+ // Signed overflow occurred if the high part does not sign extend the low.
SDValue SExt = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, Mul.getValueType(),
Mul, DAG.getValueType(SmallVT));
Overflow = DAG.getSetCC(DL, N->getValueType(1), SExt, Mul, ISD::SETNE);
}
+ // The only other way for overflow to occur is if the multiplication in the
+ // larger type itself overflowed.
+ Overflow = DAG.getNode(ISD::OR, DL, N->getValueType(1), Overflow,
+ SDValue(Mul.getNode(), 1));
+
// Use the calculated overflow everywhere.
ReplaceValueWith(SDValue(N, 1), Overflow);
return Mul;
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
index 39337fff50..644e36e35e 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
@@ -15,7 +15,7 @@
#include "LegalizeTypes.h"
#include "llvm/CallingConv.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
index 7b8f138a34..bb54fd24e2 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
@@ -20,7 +20,7 @@
//===----------------------------------------------------------------------===//
#include "LegalizeTypes.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -146,7 +146,7 @@ void DAGTypeLegalizer::ExpandRes_BITCAST(SDNode *N, SDValue &Lo, SDValue &Hi) {
// Create the stack frame object. Make sure it is aligned for both
// the source and expanded destination types.
unsigned Alignment =
- TLI.getTargetData()->getPrefTypeAlignment(NOutVT.
+ TLI.getDataLayout()->getPrefTypeAlignment(NOutVT.
getTypeForEVT(*DAG.getContext()));
SDValue StackPtr = DAG.CreateStackTemporary(InVT, Alignment);
int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 4095728ee0..eca4d99098 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -21,7 +21,7 @@
//===----------------------------------------------------------------------===//
#include "LegalizeTypes.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -749,7 +749,7 @@ void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo,
SDValue EltPtr = GetVectorElementPointer(StackPtr, EltVT, Idx);
Type *VecType = VecVT.getTypeForEVT(*DAG.getContext());
unsigned Alignment =
- TLI.getTargetData()->getPrefTypeAlignment(VecType);
+ TLI.getDataLayout()->getPrefTypeAlignment(VecType);
Store = DAG.getTruncStore(Store, dl, Elt, EltPtr, MachinePointerInfo(), EltVT,
false, false, 0);
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
index b7ce48a489..515eff3b25 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
@@ -17,7 +17,7 @@
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/ADT/SmallSet.h"
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
index 68be9ecc03..62f485153b 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -22,7 +22,7 @@
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLowering.h"
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h
index 84e41fc4a1..8e7bd82201 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h
@@ -158,6 +158,12 @@ namespace llvm {
void InitNodeNumDefs();
};
+ protected:
+ /// ForceUnitLatencies - Return true if all scheduling edges should be given
+ /// a latency value of one. The default is to return false; schedulers may
+ /// override this as needed.
+ virtual bool forceUnitLatencies() const { return false; }
+
private:
/// ClusterNeighboringLoads - Cluster loads from "near" addresses into
/// combined SUnits.
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGVLIW.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGVLIW.cpp
index c8512914c1..30f03ac737 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGVLIW.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGVLIW.cpp
@@ -25,7 +25,7 @@
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index a48a6256e5..79cfcdfe0e 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -29,7 +29,7 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetSelectionDAGInfo.h"
#include "llvm/Target/TargetOptions.h"
@@ -136,13 +136,11 @@ bool ISD::isBuildVectorAllOnes(const SDNode *N) {
// constants are.
SDValue NotZero = N->getOperand(i);
unsigned EltSize = N->getValueType(0).getVectorElementType().getSizeInBits();
- if (isa<ConstantSDNode>(NotZero)) {
- if (cast<ConstantSDNode>(NotZero)->getAPIntValue().countTrailingOnes() <
- EltSize)
+ if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(NotZero)) {
+ if (CN->getAPIntValue().countTrailingOnes() < EltSize)
return false;
- } else if (isa<ConstantFPSDNode>(NotZero)) {
- if (cast<ConstantFPSDNode>(NotZero)->getValueAPF()
- .bitcastToAPInt().countTrailingOnes() < EltSize)
+ } else if (ConstantFPSDNode *CFPN = dyn_cast<ConstantFPSDNode>(NotZero)) {
+ if (CFPN->getValueAPF().bitcastToAPInt().countTrailingOnes() < EltSize)
return false;
} else
return false;
@@ -179,11 +177,11 @@ bool ISD::isBuildVectorAllZeros(const SDNode *N) {
// Do not accept build_vectors that aren't all constants or which have non-0
// elements.
SDValue Zero = N->getOperand(i);
- if (isa<ConstantSDNode>(Zero)) {
- if (!cast<ConstantSDNode>(Zero)->isNullValue())
+ if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Zero)) {
+ if (!CN->isNullValue())
return false;
- } else if (isa<ConstantFPSDNode>(Zero)) {
- if (!cast<ConstantFPSDNode>(Zero)->getValueAPF().isPosZero())
+ } else if (ConstantFPSDNode *CFPN = dyn_cast<ConstantFPSDNode>(Zero)) {
+ if (!CFPN->getValueAPF().isPosZero())
return false;
} else
return false;
@@ -885,7 +883,7 @@ unsigned SelectionDAG::getEVTAlignment(EVT VT) const {
PointerType::get(Type::getInt8Ty(*getContext()), 0) :
VT.getTypeForEVT(*getContext());
- return TLI.getTargetData()->getABITypeAlignment(Ty);
+ return TLI.getDataLayout()->getABITypeAlignment(Ty);
}
// EntryNode could meaningfully have debug info if we can find it...
@@ -1175,7 +1173,7 @@ SDValue SelectionDAG::getConstantPool(const Constant *C, EVT VT,
assert((TargetFlags == 0 || isTarget) &&
"Cannot set target flags on target-independent globals");
if (Alignment == 0)
- Alignment = TLI.getTargetData()->getPrefTypeAlignment(C->getType());
+ Alignment = TLI.getDataLayout()->getPrefTypeAlignment(C->getType());
unsigned Opc = isTarget ? ISD::TargetConstantPool : ISD::ConstantPool;
FoldingSetNodeID ID;
AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0);
@@ -1202,7 +1200,7 @@ SDValue SelectionDAG::getConstantPool(MachineConstantPoolValue *C, EVT VT,
assert((TargetFlags == 0 || isTarget) &&
"Cannot set target flags on target-independent globals");
if (Alignment == 0)
- Alignment = TLI.getTargetData()->getPrefTypeAlignment(C->getType());
+ Alignment = TLI.getDataLayout()->getPrefTypeAlignment(C->getType());
unsigned Opc = isTarget ? ISD::TargetConstantPool : ISD::ConstantPool;
FoldingSetNodeID ID;
AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0);
@@ -1546,7 +1544,7 @@ SDValue SelectionDAG::CreateStackTemporary(EVT VT, unsigned minAlign) {
unsigned ByteSize = VT.getStoreSize();
Type *Ty = VT.getTypeForEVT(*getContext());
unsigned StackAlign =
- std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty), minAlign);
+ std::max((unsigned)TLI.getDataLayout()->getPrefTypeAlignment(Ty), minAlign);
int FrameIdx = FrameInfo->CreateStackObject(ByteSize, StackAlign, false);
return getFrameIndex(FrameIdx, TLI.getPointerTy());
@@ -1559,7 +1557,7 @@ SDValue SelectionDAG::CreateStackTemporary(EVT VT1, EVT VT2) {
VT2.getStoreSizeInBits())/8;
Type *Ty1 = VT1.getTypeForEVT(*getContext());
Type *Ty2 = VT2.getTypeForEVT(*getContext());
- const TargetData *TD = TLI.getTargetData();
+ const DataLayout *TD = TLI.getDataLayout();
unsigned Align = std::max(TD->getPrefTypeAlignment(Ty1),
TD->getPrefTypeAlignment(Ty2));
@@ -3453,7 +3451,7 @@ static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,
DAG.getMachineFunction());
if (VT == MVT::Other) {
- if (DstAlign >= TLI.getTargetData()->getPointerPrefAlignment() ||
+ if (DstAlign >= TLI.getDataLayout()->getPointerPrefAlignment() ||
TLI.allowsUnalignedMemoryAccesses(VT)) {
VT = TLI.getPointerTy();
} else {
@@ -3521,7 +3519,9 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
bool DstAlignCanChange = false;
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo *MFI = MF.getFrameInfo();
- bool OptSize = MF.getFunction()->getFnAttributes().hasOptimizeForSizeAttr();
+ bool OptSize =
+ MF.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize);
FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Dst);
if (FI && !MFI->isFixedObjectIndex(FI->getIndex()))
DstAlignCanChange = true;
@@ -3541,7 +3541,7 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
if (DstAlignCanChange) {
Type *Ty = MemOps[0].getTypeForEVT(*DAG.getContext());
- unsigned NewAlign = (unsigned) TLI.getTargetData()->getABITypeAlignment(Ty);
+ unsigned NewAlign = (unsigned) TLI.getDataLayout()->getABITypeAlignment(Ty);
if (NewAlign > Align) {
// Give the stack frame object a larger alignment if needed.
if (MFI->getObjectAlignment(FI->getIndex()) < NewAlign)
@@ -3614,7 +3614,8 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
bool DstAlignCanChange = false;
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo *MFI = MF.getFrameInfo();
- bool OptSize = MF.getFunction()->getFnAttributes().hasOptimizeForSizeAttr();
+ bool OptSize = MF.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize);
FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Dst);
if (FI && !MFI->isFixedObjectIndex(FI->getIndex()))
DstAlignCanChange = true;
@@ -3630,7 +3631,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
if (DstAlignCanChange) {
Type *Ty = MemOps[0].getTypeForEVT(*DAG.getContext());
- unsigned NewAlign = (unsigned) TLI.getTargetData()->getABITypeAlignment(Ty);
+ unsigned NewAlign = (unsigned) TLI.getDataLayout()->getABITypeAlignment(Ty);
if (NewAlign > Align) {
// Give the stack frame object a larger alignment if needed.
if (MFI->getObjectAlignment(FI->getIndex()) < NewAlign)
@@ -3692,7 +3693,8 @@ static SDValue getMemsetStores(SelectionDAG &DAG, DebugLoc dl,
bool DstAlignCanChange = false;
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo *MFI = MF.getFrameInfo();
- bool OptSize = MF.getFunction()->getFnAttributes().hasOptimizeForSizeAttr();
+ bool OptSize = MF.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize);
FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Dst);
if (FI && !MFI->isFixedObjectIndex(FI->getIndex()))
DstAlignCanChange = true;
@@ -3705,7 +3707,7 @@ static SDValue getMemsetStores(SelectionDAG &DAG, DebugLoc dl,
if (DstAlignCanChange) {
Type *Ty = MemOps[0].getTypeForEVT(*DAG.getContext());
- unsigned NewAlign = (unsigned) TLI.getTargetData()->getABITypeAlignment(Ty);
+ unsigned NewAlign = (unsigned) TLI.getDataLayout()->getABITypeAlignment(Ty);
if (NewAlign > Align) {
// Give the stack frame object a larger alignment if needed.
if (MFI->getObjectAlignment(FI->getIndex()) < NewAlign)
@@ -3799,7 +3801,7 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst,
// Emit a library call.
TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry;
- Entry.Ty = TLI.getTargetData()->getIntPtrType(*getContext());
+ Entry.Ty = TLI.getDataLayout()->getIntPtrType(*getContext());
Entry.Node = Dst; Args.push_back(Entry);
Entry.Node = Src; Args.push_back(Entry);
Entry.Node = Size; Args.push_back(Entry);
@@ -3854,7 +3856,7 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, DebugLoc dl, SDValue Dst,
// Emit a library call.
TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry;
- Entry.Ty = TLI.getTargetData()->getIntPtrType(*getContext());
+ Entry.Ty = TLI.getDataLayout()->getIntPtrType(*getContext());
Entry.Node = Dst; Args.push_back(Entry);
Entry.Node = Src; Args.push_back(Entry);
Entry.Node = Size; Args.push_back(Entry);
@@ -3903,7 +3905,7 @@ SDValue SelectionDAG::getMemset(SDValue Chain, DebugLoc dl, SDValue Dst,
return Result;
// Emit a library call.
- Type *IntPtrTy = TLI.getTargetData()->getIntPtrType(*getContext());
+ Type *IntPtrTy = TLI.getDataLayout()->getIntPtrType(*getContext());
TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry;
Entry.Node = Dst; Entry.Ty = IntPtrTy;
@@ -6099,7 +6101,7 @@ unsigned SelectionDAG::InferPtrAlignment(SDValue Ptr) const {
unsigned PtrWidth = TLI.getPointerTy().getSizeInBits();
APInt KnownZero(PtrWidth, 0), KnownOne(PtrWidth, 0);
llvm::ComputeMaskedBits(const_cast<GlobalValue*>(GV), KnownZero, KnownOne,
- TLI.getTargetData());
+ TLI.getDataLayout());
unsigned AlignBits = KnownZero.countTrailingOnes();
unsigned Align = AlignBits ? 1 << std::min(31U, AlignBits) : 0;
if (Align)
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 65becbe44f..cde22a5ce0 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -44,7 +44,7 @@
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetIntrinsicInfo.h"
@@ -847,7 +847,7 @@ void SelectionDAGBuilder::init(GCFunctionInfo *gfi, AliasAnalysis &aa,
AA = &aa;
GFI = gfi;
LibInfo = li;
- TD = DAG.getTarget().getTargetData();
+ TD = DAG.getTarget().getDataLayout();
Context = DAG.getContext();
LPadToCallSiteMap.clear();
}
@@ -1227,9 +1227,9 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
const Function *F = I.getParent()->getParent();
- if (F->paramHasAttr(0, Attribute::SExt))
+ if (F->getRetAttributes().hasAttribute(Attributes::SExt))
ExtendKind = ISD::SIGN_EXTEND;
- else if (F->paramHasAttr(0, Attribute::ZExt))
+ else if (F->getRetAttributes().hasAttribute(Attributes::ZExt))
ExtendKind = ISD::ZERO_EXTEND;
if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger())
@@ -1244,7 +1244,7 @@ void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
// 'inreg' on function refers to return value
ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy();
- if (F->paramHasAttr(0, Attribute::InReg))
+ if (F->getRetAttributes().hasAttribute(Attributes::InReg))
Flags.setInReg();
// Propagate extension type if any
@@ -3208,9 +3208,9 @@ void SelectionDAGBuilder::visitAlloca(const AllocaInst &I) {
return; // getValue will auto-populate this.
Type *Ty = I.getAllocatedType();
- uint64_t TySize = TLI.getTargetData()->getTypeAllocSize(Ty);
+ uint64_t TySize = TLI.getDataLayout()->getTypeAllocSize(Ty);
unsigned Align =
- std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty),
+ std::max((unsigned)TLI.getDataLayout()->getPrefTypeAlignment(Ty),
I.getAlignment());
SDValue AllocSize = getValue(I.getArraySize());
@@ -4400,7 +4400,7 @@ static SDValue ExpandPowI(DebugLoc DL, SDValue LHS, SDValue RHS,
return DAG.getConstantFP(1.0, LHS.getValueType());
const Function *F = DAG.getMachineFunction().getFunction();
- if (!F->getFnAttributes().hasOptimizeForSizeAttr() ||
+ if (!F->getFnAttributes().hasAttribute(Attributes::OptimizeForSize) ||
// If optimizing for size, don't insert too many multiplies. This
// inserts up to 5 multiplies.
CountPopulation_32(Val)+Log2_32(Val) < 7) {
@@ -5330,9 +5330,9 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee,
int DemoteStackIdx = -100;
if (!CanLowerReturn) {
- uint64_t TySize = TLI.getTargetData()->getTypeAllocSize(
+ uint64_t TySize = TLI.getDataLayout()->getTypeAllocSize(
FTy->getReturnType());
- unsigned Align = TLI.getTargetData()->getPrefTypeAlignment(
+ unsigned Align = TLI.getDataLayout()->getPrefTypeAlignment(
FTy->getReturnType());
MachineFunction &MF = DAG.getMachineFunction();
DemoteStackIdx = MF.getFrameInfo()->CreateStackObject(TySize, Align, false);
@@ -5364,12 +5364,12 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee,
Entry.Node = ArgNode; Entry.Ty = V->getType();
unsigned attrInd = i - CS.arg_begin() + 1;
- Entry.isSExt = CS.paramHasAttr(attrInd, Attribute::SExt);
- Entry.isZExt = CS.paramHasAttr(attrInd, Attribute::ZExt);
- Entry.isInReg = CS.paramHasAttr(attrInd, Attribute::InReg);
- Entry.isSRet = CS.paramHasAttr(attrInd, Attribute::StructRet);
- Entry.isNest = CS.paramHasAttr(attrInd, Attribute::Nest);
- Entry.isByVal = CS.paramHasAttr(attrInd, Attribute::ByVal);
+ Entry.isSExt = CS.paramHasAttr(attrInd, Attributes::SExt);
+ Entry.isZExt = CS.paramHasAttr(attrInd, Attributes::ZExt);
+ Entry.isInReg = CS.paramHasAttr(attrInd, Attributes::InReg);
+ Entry.isSRet = CS.paramHasAttr(attrInd, Attributes::StructRet);
+ Entry.isNest = CS.paramHasAttr(attrInd, Attributes::Nest);
+ Entry.isByVal = CS.paramHasAttr(attrInd, Attributes::ByVal);
Entry.Alignment = CS.getParamAlignment(attrInd);
Args.push_back(Entry);
}
@@ -5797,7 +5797,7 @@ public:
/// MVT::Other.
EVT getCallOperandValEVT(LLVMContext &Context,
const TargetLowering &TLI,
- const TargetData *TD) const {
+ const DataLayout *TD) const {
if (CallOperandVal == 0) return MVT::Other;
if (isa<BasicBlock>(CallOperandVal))
@@ -6101,8 +6101,8 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {
// Otherwise, create a stack slot and emit a store to it before the
// asm.
Type *Ty = OpVal->getType();
- uint64_t TySize = TLI.getTargetData()->getTypeAllocSize(Ty);
- unsigned Align = TLI.getTargetData()->getPrefTypeAlignment(Ty);
+ uint64_t TySize = TLI.getDataLayout()->getTypeAllocSize(Ty);
+ unsigned Align = TLI.getDataLayout()->getPrefTypeAlignment(Ty);
MachineFunction &MF = DAG.getMachineFunction();
int SSFI = MF.getFrameInfo()->CreateStackObject(TySize, Align, false);
SDValue StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
@@ -6450,7 +6450,7 @@ void SelectionDAGBuilder::visitVAStart(const CallInst &I) {
}
void SelectionDAGBuilder::visitVAArg(const VAArgInst &I) {
- const TargetData &TD = *TLI.getTargetData();
+ const DataLayout &TD = *TLI.getDataLayout();
SDValue V = DAG.getVAArg(TLI.getValueType(I.getType()), getCurDebugLoc(),
getRoot(), getValue(I.getOperand(0)),
DAG.getSrcValue(I.getOperand(0)),
@@ -6499,7 +6499,7 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
Args[i].Node.getResNo() + Value);
ISD::ArgFlagsTy Flags;
unsigned OriginalAlignment =
- getTargetData()->getABITypeAlignment(ArgTy);
+ getDataLayout()->getABITypeAlignment(ArgTy);
if (Args[i].isZExt)
Flags.setZExt();
@@ -6513,7 +6513,7 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
Flags.setByVal();
PointerType *Ty = cast<PointerType>(Args[i].Ty);
Type *ElementTy = Ty->getElementType();
- Flags.setByValSize(getTargetData()->getTypeAllocSize(ElementTy));
+ Flags.setByValSize(getDataLayout()->getTypeAllocSize(ElementTy));
// For ByVal, alignment should come from FE. BE will guess if this
// info is not there but there are cases it cannot get right.
unsigned FrameAlign;
@@ -6688,7 +6688,7 @@ void SelectionDAGISel::LowerArguments(const BasicBlock *LLVMBB) {
const Function &F = *LLVMBB->getParent();
SelectionDAG &DAG = SDB->DAG;
DebugLoc dl = SDB->getCurDebugLoc();
- const TargetData *TD = TLI.getTargetData();
+ const DataLayout *TD = TLI.getDataLayout();
SmallVector<ISD::InputArg, 16> Ins;
// Check whether the function can return without sret-demotion.
@@ -6725,15 +6725,15 @@ void SelectionDAGISel::LowerArguments(const BasicBlock *LLVMBB) {
unsigned OriginalAlignment =
TD->getABITypeAlignment(ArgTy);
- if (F.paramHasAttr(Idx, Attribute::ZExt))
+ if (F.getParamAttributes(Idx).hasAttribute(Attributes::ZExt))
Flags.setZExt();
- if (F.paramHasAttr(Idx, Attribute::SExt))
+ if (F.getParamAttributes(Idx).hasAttribute(Attributes::SExt))
Flags.setSExt();
- if (F.paramHasAttr(Idx, Attribute::InReg))
+ if (F.getParamAttributes(Idx).hasAttribute(Attributes::InReg))
Flags.setInReg();
- if (F.paramHasAttr(Idx, Attribute::StructRet))
+ if (F.getParamAttributes(Idx).hasAttribute(Attributes::StructRet))
Flags.setSRet();
- if (F.paramHasAttr(Idx, Attribute::ByVal)) {
+ if (F.getParamAttributes(Idx).hasAttribute(Attributes::ByVal)) {
Flags.setByVal();
PointerType *Ty = cast<PointerType>(I->getType());
Type *ElementTy = Ty->getElementType();
@@ -6747,7 +6747,7 @@ void SelectionDAGISel::LowerArguments(const BasicBlock *LLVMBB) {
FrameAlign = TLI.getByValTypeAlignment(ElementTy);
Flags.setByValAlign(FrameAlign);
}
- if (F.paramHasAttr(Idx, Attribute::Nest))
+ if (F.getParamAttributes(Idx).hasAttribute(Attributes::Nest))
Flags.setNest();
Flags.setOrigAlign(OriginalAlignment);
@@ -6834,9 +6834,9 @@ void SelectionDAGISel::LowerArguments(const BasicBlock *LLVMBB) {
if (!I->use_empty()) {
ISD::NodeType AssertOp = ISD::DELETED_NODE;
- if (F.paramHasAttr(Idx, Attribute::SExt))
+ if (F.getParamAttributes(Idx).hasAttribute(Attributes::SExt))
AssertOp = ISD::AssertSext;
- else if (F.paramHasAttr(Idx, Attribute::ZExt))
+ else if (F.getParamAttributes(Idx).hasAttribute(Attributes::ZExt))
AssertOp = ISD::AssertZext;
ArgValues.push_back(getCopyFromParts(DAG, dl, &InVals[i],
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
index 3b7615a757..9e46d9664f 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -66,7 +66,7 @@ class ShuffleVectorInst;
class SIToFPInst;
class StoreInst;
class SwitchInst;
-class TargetData;
+class DataLayout;
class TargetLibraryInfo;
class TargetLowering;
class TruncInst;
@@ -285,7 +285,7 @@ public:
const TargetMachine &TM;
const TargetLowering &TLI;
SelectionDAG &DAG;
- const TargetData *TD;
+ const DataLayout *TD;
AliasAnalysis *AA;
const TargetLibraryInfo *LibInfo;
diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index be3ecf34f7..cd485ac235 100644
--- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -14,7 +14,7 @@
#include "llvm/Target/TargetLowering.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCExpr.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
@@ -515,7 +515,7 @@ static void InitCmpLibcallCCs(ISD::CondCode *CCs) {
/// NOTE: The constructor takes ownership of TLOF.
TargetLowering::TargetLowering(const TargetMachine &tm,
const TargetLoweringObjectFile *tlof)
- : TM(tm), TD(TM.getTargetData()), TLOF(*tlof) {
+ : TM(tm), TD(TM.getDataLayout()), TLOF(*tlof) {
// All operations default to being supported.
memset(OpActions, 0, sizeof(OpActions));
memset(LoadExtActions, 0, sizeof(LoadExtActions));
@@ -584,7 +584,7 @@ TargetLowering::TargetLowering(const TargetMachine &tm,
setOperationAction(ISD::TRAP, MVT::Other, Expand);
IsLittleEndian = TD->isLittleEndian();
- PointerTy = MVT::getIntegerVT(8*TD->getPointerSize());
+ PointerTy = MVT::getIntegerVT(8*TD->getPointerSize(0));
memset(RegClassForVT, 0,MVT::LAST_VALUETYPE*sizeof(TargetRegisterClass*));
memset(TargetDAGCombineArray, 0, array_lengthof(TargetDAGCombineArray));
maxStoresPerMemset = maxStoresPerMemcpy = maxStoresPerMemmove = 8;
@@ -625,7 +625,7 @@ TargetLowering::~TargetLowering() {
}
MVT TargetLowering::getShiftAmountTy(EVT LHSTy) const {
- return MVT::getIntegerVT(8*TD->getPointerSize());
+ return MVT::getIntegerVT(8*TD->getPointerSize(0));
}
/// canOpTrap - Returns true if the operation can trap for the value type.
@@ -901,7 +901,7 @@ const char *TargetLowering::getTargetNodeName(unsigned Opcode) const {
EVT TargetLowering::getSetCCResultType(EVT VT) const {
assert(!VT.isVector() && "No default SetCC type for vectors!");
- return PointerTy.SimpleTy;
+ return getPointerTy(0).SimpleTy;
}
MVT::SimpleValueType TargetLowering::getCmpLibcallReturnType() const {
@@ -997,9 +997,9 @@ void llvm::GetReturnInfo(Type* ReturnType, Attributes attr,
EVT VT = ValueVTs[j];
ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
- if (attr.hasSExtAttr())
+ if (attr.hasAttribute(Attributes::SExt))
ExtendKind = ISD::SIGN_EXTEND;
- else if (attr.hasZExtAttr())
+ else if (attr.hasAttribute(Attributes::ZExt))
ExtendKind = ISD::ZERO_EXTEND;
// FIXME: C calling convention requires the return type to be promoted to
@@ -1017,13 +1017,13 @@ void llvm::GetReturnInfo(Type* ReturnType, Attributes attr,
// 'inreg' on function refers to return value
ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy();
- if (attr.hasInRegAttr())
+ if (attr.hasAttribute(Attributes::InReg))
Flags.setInReg();
// Propagate extension type if any
- if (attr.hasSExtAttr())
+ if (attr.hasAttribute(Attributes::SExt))
Flags.setSExt();
- else if (attr.hasZExtAttr())
+ else if (attr.hasAttribute(Attributes::ZExt))
Flags.setZExt();
for (unsigned i = 0; i < NumParts; ++i)
@@ -1061,7 +1061,7 @@ SDValue TargetLowering::getPICJumpTableRelocBase(SDValue Table,
if ((JTEncoding == MachineJumpTableInfo::EK_GPRel64BlockAddress) ||
(JTEncoding == MachineJumpTableInfo::EK_GPRel32BlockAddress))
- return DAG.getGLOBAL_OFFSET_TABLE(getPointerTy());
+ return DAG.getGLOBAL_OFFSET_TABLE(getPointerTy(0));
return Table;
}
@@ -2953,8 +2953,9 @@ TargetLowering::AsmOperandInfoVector TargetLowering::ParseConstraints(
EVT::getEVT(IntegerType::get(OpTy->getContext(), BitSize), true);
break;
}
- } else if (dyn_cast<PointerType>(OpTy)) {
- OpInfo.ConstraintVT = MVT::getIntegerVT(8*TD->getPointerSize());
+ } else if (PointerType *PT = dyn_cast<PointerType>(OpTy)) {
+ OpInfo.ConstraintVT = MVT::getIntegerVT(
+ 8*TD->getPointerSize(PT->getAddressSpace()));
} else {
OpInfo.ConstraintVT = EVT::getEVT(OpTy, true);
}
diff --git a/lib/CodeGen/SelectionDAG/TargetSelectionDAGInfo.cpp b/lib/CodeGen/SelectionDAG/TargetSelectionDAGInfo.cpp
index a081e3cd49..f769b44efb 100644
--- a/lib/CodeGen/SelectionDAG/TargetSelectionDAGInfo.cpp
+++ b/lib/CodeGen/SelectionDAG/TargetSelectionDAGInfo.cpp
@@ -16,7 +16,7 @@
using namespace llvm;
TargetSelectionDAGInfo::TargetSelectionDAGInfo(const TargetMachine &TM)
- : TD(TM.getTargetData()) {
+ : TD(TM.getDataLayout()) {
}
TargetSelectionDAGInfo::~TargetSelectionDAGInfo() {
diff --git a/lib/CodeGen/SjLjEHPrepare.cpp b/lib/CodeGen/SjLjEHPrepare.cpp
index 7f46a062fa..4b566fcba9 100644
--- a/lib/CodeGen/SjLjEHPrepare.cpp
+++ b/lib/CodeGen/SjLjEHPrepare.cpp
@@ -30,7 +30,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
@@ -191,7 +191,7 @@ setupFunctionContext(Function &F, ArrayRef<LandingPadInst*> LPads) {
// that needs to be restored on all exits from the function. This is an alloca
// because the value needs to be added to the global context list.
unsigned Align =
- TLI->getTargetData()->getPrefTypeAlignment(FunctionContextTy);
+ TLI->getDataLayout()->getPrefTypeAlignment(FunctionContextTy);
FuncCtx =
new AllocaInst(FunctionContextTy, 0, Align, "fn_context", EntryBB->begin());
diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp
index a58c144659..31e9ec0ac0 100644
--- a/lib/CodeGen/StackProtector.cpp
+++ b/lib/CodeGen/StackProtector.cpp
@@ -26,7 +26,7 @@
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/Triple.h"
@@ -117,7 +117,7 @@ bool StackProtector::ContainsProtectableArray(Type *Ty, bool InStruct) const {
// If an array has more than SSPBufferSize bytes of allocated space, then we
// emit stack protectors.
- if (TM.Options.SSPBufferSize <= TLI->getTargetData()->getTypeAllocSize(AT))
+ if (TM.Options.SSPBufferSize <= TLI->getDataLayout()->getTypeAllocSize(AT))
return true;
}
@@ -137,10 +137,10 @@ bool StackProtector::ContainsProtectableArray(Type *Ty, bool InStruct) const {
/// add a guard variable to functions that call alloca, and functions with
/// buffers larger than SSPBufferSize bytes.
bool StackProtector::RequiresStackProtector() const {
- if (F->getFnAttributes().hasStackProtectReqAttr())
+ if (F->getFnAttributes().hasAttribute(Attributes::StackProtectReq))
return true;
- if (!F->getFnAttributes().hasStackProtectAttr())
+ if (!F->getFnAttributes().hasAttribute(Attributes::StackProtect))
return false;
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
diff --git a/lib/CodeGen/TailDuplication.cpp b/lib/CodeGen/TailDuplication.cpp
index 230ea038e2..1497d1ba62 100644
--- a/lib/CodeGen/TailDuplication.cpp
+++ b/lib/CodeGen/TailDuplication.cpp
@@ -552,7 +552,8 @@ TailDuplicatePass::shouldTailDuplicate(const MachineFunction &MF,
// compensate for the duplication.
unsigned MaxDuplicateCount;
if (TailDuplicateSize.getNumOccurrences() == 0 &&
- MF.getFunction()->getFnAttributes().hasOptimizeForSizeAttr())
+ MF.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize))
MaxDuplicateCount = 1;
else
MaxDuplicateCount = TailDuplicateSize;
diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 75c9467a4f..6df4a0aa2a 100644
--- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -27,7 +27,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Dwarf.h"
@@ -93,9 +93,9 @@ void TargetLoweringObjectFileELF::emitPersonalityValue(MCStreamer &Streamer,
Flags,
SectionKind::getDataRel(),
0, Label->getName());
- unsigned Size = TM.getTargetData()->getPointerSize();
+ unsigned Size = TM.getDataLayout()->getPointerSize();
Streamer.SwitchSection(Sec);
- Streamer.EmitValueToAlignment(TM.getTargetData()->getPointerABIAlignment());
+ Streamer.EmitValueToAlignment(TM.getDataLayout()->getPointerABIAlignment());
Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject);
const MCExpr *E = MCConstantExpr::Create(Size, getContext());
Streamer.EmitELFSize(Label, E);
@@ -263,7 +263,7 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
// FIXME: this is getting the alignment of the character, not the
// alignment of the global!
unsigned Align =
- TM.getTargetData()->getPreferredAlignment(cast<GlobalVariable>(GV));
+ TM.getDataLayout()->getPreferredAlignment(cast<GlobalVariable>(GV));
const char *SizeSpec = ".rodata.str1.";
if (Kind.isMergeable2ByteCString())
@@ -538,14 +538,14 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
// FIXME: Alignment check should be handled by section classifier.
if (Kind.isMergeable1ByteCString() &&
- TM.getTargetData()->getPreferredAlignment(cast<GlobalVariable>(GV)) < 32)
+ TM.getDataLayout()->getPreferredAlignment(cast<GlobalVariable>(GV)) < 32)
return CStringSection;
// Do not put 16-bit arrays in the UString section if they have an
// externally visible label, this runs into issues with certain linker
// versions.
if (Kind.isMergeable2ByteCString() && !GV->hasExternalLinkage() &&
- TM.getTargetData()->getPreferredAlignment(cast<GlobalVariable>(GV)) < 32)
+ TM.getDataLayout()->getPreferredAlignment(cast<GlobalVariable>(GV)) < 32)
return UStringSection;
if (Kind.isMergeableConst()) {
diff --git a/lib/CodeGen/TargetSchedule.cpp b/lib/CodeGen/TargetSchedule.cpp
index 353c9cf8aa..2c98982ee2 100644
--- a/lib/CodeGen/TargetSchedule.cpp
+++ b/lib/CodeGen/TargetSchedule.cpp
@@ -21,7 +21,7 @@
using namespace llvm;
-static cl::opt<bool> EnableSchedModel("schedmodel", cl::Hidden, cl::init(false),
+static cl::opt<bool> EnableSchedModel("schedmodel", cl::Hidden, cl::init(true),
cl::desc("Use TargetSchedModel for latency lookup"));
static cl::opt<bool> EnableSchedItins("scheditins", cl::Hidden, cl::init(true),
@@ -123,60 +123,59 @@ unsigned TargetSchedModel::computeOperandLatency(
if (DefLatency >= 0)
return DefLatency;
- if (!FindMin && EnableSchedModel && hasInstrSchedModel()) {
- const MCSchedClassDesc *SCDesc = resolveSchedClass(DefMI);
- unsigned DefIdx = findDefIdx(DefMI, DefOperIdx);
- if (DefIdx < SCDesc->NumWriteLatencyEntries) {
- // Lookup the definition's write latency in SubtargetInfo.
- const MCWriteLatencyEntry *WLEntry =
- STI->getWriteLatencyEntry(SCDesc, DefIdx);
- unsigned WriteID = WLEntry->WriteResourceID;
- unsigned Latency = WLEntry->Cycles;
- if (!UseMI)
- return Latency;
-
- // Lookup the use's latency adjustment in SubtargetInfo.
- const MCSchedClassDesc *UseDesc = resolveSchedClass(UseMI);
- if (UseDesc->NumReadAdvanceEntries == 0)
- return Latency;
- unsigned UseIdx = findUseIdx(UseMI, UseOperIdx);
- return Latency - STI->getReadAdvanceCycles(UseDesc, UseIdx, WriteID);
+ if (EnableSchedItins && hasInstrItineraries()) {
+ int OperLatency = 0;
+ if (UseMI) {
+ OperLatency =
+ TII->getOperandLatency(&InstrItins, DefMI, DefOperIdx, UseMI, UseOperIdx);
}
- // If DefIdx does not exist in the model (e.g. implicit defs), then return
- // unit latency (defaultDefLatency may be too conservative).
-#ifndef NDEBUG
- if (SCDesc->isValid() && !DefMI->getOperand(DefOperIdx).isImplicit()
- && !DefMI->getDesc().OpInfo[DefOperIdx].isOptionalDef()) {
- std::string Err;
- raw_string_ostream ss(Err);
- ss << "DefIdx " << DefIdx << " exceeds machine model writes for "
- << *DefMI;
- report_fatal_error(ss.str());
+ else {
+ unsigned DefClass = DefMI->getDesc().getSchedClass();
+ OperLatency = InstrItins.getOperandCycle(DefClass, DefOperIdx);
}
-#endif
- return 1;
- }
- assert(EnableSchedItins && hasInstrItineraries() &&
- "operand latency requires itinerary");
+ if (OperLatency >= 0)
+ return OperLatency;
- int OperLatency = 0;
- if (UseMI) {
- OperLatency =
- TII->getOperandLatency(&InstrItins, DefMI, DefOperIdx, UseMI, UseOperIdx);
+ // No operand latency was found.
+ unsigned InstrLatency = TII->getInstrLatency(&InstrItins, DefMI);
+
+ // Expected latency is the max of the stage latency and itinerary props.
+ if (!FindMin)
+ InstrLatency = std::max(InstrLatency,
+ TII->defaultDefLatency(&SchedModel, DefMI));
+ return InstrLatency;
}
- else {
- unsigned DefClass = DefMI->getDesc().getSchedClass();
- OperLatency = InstrItins.getOperandCycle(DefClass, DefOperIdx);
+ assert(!FindMin && EnableSchedModel && hasInstrSchedModel() &&
+ "Expected a SchedModel for this cpu");
+ const MCSchedClassDesc *SCDesc = resolveSchedClass(DefMI);
+ unsigned DefIdx = findDefIdx(DefMI, DefOperIdx);
+ if (DefIdx < SCDesc->NumWriteLatencyEntries) {
+ // Lookup the definition's write latency in SubtargetInfo.
+ const MCWriteLatencyEntry *WLEntry =
+ STI->getWriteLatencyEntry(SCDesc, DefIdx);
+ unsigned WriteID = WLEntry->WriteResourceID;
+ unsigned Latency = WLEntry->Cycles;
+ if (!UseMI)
+ return Latency;
+
+ // Lookup the use's latency adjustment in SubtargetInfo.
+ const MCSchedClassDesc *UseDesc = resolveSchedClass(UseMI);
+ if (UseDesc->NumReadAdvanceEntries == 0)
+ return Latency;
+ unsigned UseIdx = findUseIdx(UseMI, UseOperIdx);
+ return Latency - STI->getReadAdvanceCycles(UseDesc, UseIdx, WriteID);
}
- if (OperLatency >= 0)
- return OperLatency;
-
- // No operand latency was found.
- unsigned InstrLatency = TII->getInstrLatency(&InstrItins, DefMI);
-
- // Expected latency is the max of the stage latency and itinerary props.
- if (!FindMin)
- InstrLatency = std::max(InstrLatency,
- TII->defaultDefLatency(&SchedModel, DefMI));
- return InstrLatency;
+ // If DefIdx does not exist in the model (e.g. implicit defs), then return
+ // unit latency (defaultDefLatency may be too conservative).
+#ifndef NDEBUG
+ if (SCDesc->isValid() && !DefMI->getOperand(DefOperIdx).isImplicit()
+ && !DefMI->getDesc().OpInfo[DefOperIdx].isOptionalDef()) {
+ std::string Err;
+ raw_string_ostream ss(Err);
+ ss << "DefIdx " << DefIdx << " exceeds machine model writes for "
+ << *DefMI;
+ report_fatal_error(ss.str());
+ }
+#endif
+ return 1;
}
diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp
index ba0aeca58d..c5c46815a2 100644
--- a/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -29,7 +29,7 @@
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/TargetRegistry.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include <cmath>
#include <cstring>
@@ -91,11 +91,11 @@ class GVMemoryBlock : public CallbackVH {
public:
/// \brief Returns the address the GlobalVariable should be written into. The
/// GVMemoryBlock object prefixes that.
- static char *Create(const GlobalVariable *GV, const TargetData& TD) {
+ static char *Create(const GlobalVariable *GV, const DataLayout& TD) {
Type *ElTy = GV->getType()->getElementType();
size_t GVSize = (size_t)TD.getTypeAllocSize(ElTy);
void *RawMemory = ::operator new(
- TargetData::RoundUpAlignment(sizeof(GVMemoryBlock),
+ DataLayout::RoundUpAlignment(sizeof(GVMemoryBlock),
TD.getPreferredAlignment(GV))
+ GVSize);
new(RawMemory) GVMemoryBlock(GV);
@@ -113,7 +113,7 @@ public:
} // anonymous namespace
char *ExecutionEngine::getMemoryForGV(const GlobalVariable *GV) {
- return GVMemoryBlock::Create(GV, *getTargetData());
+ return GVMemoryBlock::Create(GV, *getDataLayout());
}
bool ExecutionEngine::removeModule(Module *M) {
@@ -267,7 +267,7 @@ public:
void *ArgvArray::reset(LLVMContext &C, ExecutionEngine *EE,
const std::vector<std::string> &InputArgv) {
clear(); // Free the old contents.
- unsigned PtrSize = EE->getTargetData()->getPointerSize();
+ unsigned PtrSize = EE->getDataLayout()->getPointerSize();
Array = new char[(InputArgv.size()+1)*PtrSize];
DEBUG(dbgs() << "JIT: ARGV = " << (void*)Array << "\n");
@@ -342,7 +342,7 @@ void ExecutionEngine::runStaticConstructorsDestructors(bool isDtors) {
#ifndef NDEBUG
/// isTargetNullPtr - Return whether the target pointer stored at Loc is null.
static bool isTargetNullPtr(ExecutionEngine *EE, void *Loc) {
- unsigned PtrSize = EE->getTargetData()->getPointerSize();
+ unsigned PtrSize = EE->getDataLayout()->getPointerSize();
for (unsigned i = 0; i < PtrSize; ++i)
if (*(i + (uint8_t*)Loc))
return false;
@@ -856,7 +856,7 @@ static void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst,
void ExecutionEngine::StoreValueToMemory(const GenericValue &Val,
GenericValue *Ptr, Type *Ty) {
- const unsigned StoreBytes = getTargetData()->getTypeStoreSize(Ty);
+ const unsigned StoreBytes = getDataLayout()->getTypeStoreSize(Ty);
switch (Ty->getTypeID()) {
case Type::IntegerTyID:
@@ -882,7 +882,7 @@ void ExecutionEngine::StoreValueToMemory(const GenericValue &Val,
dbgs() << "Cannot store value of type " << *Ty << "!\n";
}
- if (sys::isLittleEndianHost() != getTargetData()->isLittleEndian())
+ if (sys::isLittleEndianHost() != getDataLayout()->isLittleEndian())
// Host and target are different endian - reverse the stored bytes.
std::reverse((uint8_t*)Ptr, StoreBytes + (uint8_t*)Ptr);
}
@@ -918,7 +918,7 @@ static void LoadIntFromMemory(APInt &IntVal, uint8_t *Src, unsigned LoadBytes) {
void ExecutionEngine::LoadValueFromMemory(GenericValue &Result,
GenericValue *Ptr,
Type *Ty) {
- const unsigned LoadBytes = getTargetData()->getTypeStoreSize(Ty);
+ const unsigned LoadBytes = getDataLayout()->getTypeStoreSize(Ty);
switch (Ty->getTypeID()) {
case Type::IntegerTyID:
@@ -959,20 +959,20 @@ void ExecutionEngine::InitializeMemory(const Constant *Init, void *Addr) {
if (const ConstantVector *CP = dyn_cast<ConstantVector>(Init)) {
unsigned ElementSize =
- getTargetData()->getTypeAllocSize(CP->getType()->getElementType());
+ getDataLayout()->getTypeAllocSize(CP->getType()->getElementType());
for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
InitializeMemory(CP->getOperand(i), (char*)Addr+i*ElementSize);
return;
}
if (isa<ConstantAggregateZero>(Init)) {
- memset(Addr, 0, (size_t)getTargetData()->getTypeAllocSize(Init->getType()));
+ memset(Addr, 0, (size_t)getDataLayout()->getTypeAllocSize(Init->getType()));
return;
}
if (const ConstantArray *CPA = dyn_cast<ConstantArray>(Init)) {
unsigned ElementSize =
- getTargetData()->getTypeAllocSize(CPA->getType()->getElementType());
+ getDataLayout()->getTypeAllocSize(CPA->getType()->getElementType());
for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i)
InitializeMemory(CPA->getOperand(i), (char*)Addr+i*ElementSize);
return;
@@ -980,7 +980,7 @@ void ExecutionEngine::InitializeMemory(const Constant *Init, void *Addr) {
if (const ConstantStruct *CPS = dyn_cast<ConstantStruct>(Init)) {
const StructLayout *SL =
- getTargetData()->getStructLayout(cast<StructType>(CPS->getType()));
+ getDataLayout()->getStructLayout(cast<StructType>(CPS->getType()));
for (unsigned i = 0, e = CPS->getNumOperands(); i != e; ++i)
InitializeMemory(CPS->getOperand(i), (char*)Addr+SL->getElementOffset(i));
return;
@@ -1127,7 +1127,7 @@ void ExecutionEngine::EmitGlobalVariable(const GlobalVariable *GV) {
InitializeMemory(GV->getInitializer(), GA);
Type *ElTy = GV->getType()->getElementType();
- size_t GVSize = (size_t)getTargetData()->getTypeAllocSize(ElTy);
+ size_t GVSize = (size_t)getDataLayout()->getTypeAllocSize(ElTy);
NumInitBytes += (unsigned)GVSize;
++NumGlobals;
}
diff --git a/lib/ExecutionEngine/ExecutionEngineBindings.cpp b/lib/ExecutionEngine/ExecutionEngineBindings.cpp
index 75e680ab36..1e790e781d 100644
--- a/lib/ExecutionEngine/ExecutionEngineBindings.cpp
+++ b/lib/ExecutionEngine/ExecutionEngineBindings.cpp
@@ -239,7 +239,7 @@ void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE, LLVMValueRef Fn)
}
LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE) {
- return wrap(unwrap(EE)->getTargetData());
+ return wrap(unwrap(EE)->getDataLayout());
}
void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
diff --git a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
index d99b666345..e3b90fdf78 100644
--- a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
+++ b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
@@ -25,7 +25,7 @@
#include "llvm/Config/config.h" // Detect libffi
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/DynamicLibrary.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Mutex.h"
#include <csignal>
@@ -180,7 +180,7 @@ static void *ffiValueFor(Type *Ty, const GenericValue &AV,
static bool ffiInvoke(RawFunc Fn, Function *F,
const std::vector<GenericValue> &ArgVals,
- const TargetData *TD, GenericValue &Result) {
+ const DataLayout *TD, GenericValue &Result) {
ffi_cif cif;
FunctionType *FTy = F->getFunctionType();
const unsigned NumArgs = F->arg_size();
@@ -276,7 +276,7 @@ GenericValue Interpreter::callExternalFunction(Function *F,
FunctionsLock->release();
GenericValue Result;
- if (RawFn != 0 && ffiInvoke(RawFn, F, ArgVals, getTargetData(), Result))
+ if (RawFn != 0 && ffiInvoke(RawFn, F, ArgVals, getDataLayout(), Result))
return Result;
#endif // USE_LIBFFI
@@ -378,7 +378,7 @@ GenericValue lle_X_sprintf(FunctionType *FT,
case 'x': case 'X':
if (HowLong >= 1) {
if (HowLong == 1 &&
- TheInterpreter->getTargetData()->getPointerSizeInBits() == 64 &&
+ TheInterpreter->getDataLayout()->getPointerSizeInBits() == 64 &&
sizeof(long) < sizeof(int64_t)) {
// Make sure we use %lld with a 64 bit argument because we might be
// compiling LLI on a 32 bit compiler.
diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.cpp b/lib/ExecutionEngine/Interpreter/Interpreter.cpp
index 43e34533c7..55152dbbea 100644
--- a/lib/ExecutionEngine/Interpreter/Interpreter.cpp
+++ b/lib/ExecutionEngine/Interpreter/Interpreter.cpp
@@ -48,7 +48,7 @@ Interpreter::Interpreter(Module *M)
: ExecutionEngine(M), TD(M) {
memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped));
- setTargetData(&TD);
+ setDataLayout(&TD);
// Initialize the "backend"
initializeExecutionEngine();
initializeExternalFunctions();
diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.h b/lib/ExecutionEngine/Interpreter/Interpreter.h
index 28c5775ab4..72c42c15db 100644
--- a/lib/ExecutionEngine/Interpreter/Interpreter.h
+++ b/lib/ExecutionEngine/Interpreter/Interpreter.h
@@ -17,7 +17,7 @@
#include "llvm/Function.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/GenericValue.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
@@ -82,7 +82,7 @@ struct ExecutionContext {
//
class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> {
GenericValue ExitValue; // The return value of the called function
- TargetData TD;
+ DataLayout TD;
IntrinsicLowering *IL;
// The runtime stack of executing code. The top of the stack is the current
diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp
index 97995ad95c..1ad338203a 100644
--- a/lib/ExecutionEngine/JIT/JIT.cpp
+++ b/lib/ExecutionEngine/JIT/JIT.cpp
@@ -24,7 +24,7 @@
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetJITInfo.h"
#include "llvm/Support/Dwarf.h"
@@ -272,7 +272,7 @@ JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
: ExecutionEngine(M), TM(tm), TJI(tji),
JMM(jmm ? jmm : JITMemoryManager::CreateDefaultMemManager()),
AllocateGVsWithCode(GVsWithCode), isAlreadyCodeGenerating(false) {
- setTargetData(TM.getTargetData());
+ setDataLayout(TM.getDataLayout());
jitstate = new JITState(M);
@@ -285,7 +285,7 @@ JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
// Add target data
MutexGuard locked(lock);
FunctionPassManager &PM = jitstate->getPM(locked);
- PM.add(new TargetData(*TM.getTargetData()));
+ PM.add(new DataLayout(*TM.getDataLayout()));
// Turn the machine code intermediate representation into bytes in memory that
// may be executed.
@@ -339,7 +339,7 @@ void JIT::addModule(Module *M) {
jitstate = new JITState(M);
FunctionPassManager &PM = jitstate->getPM(locked);
- PM.add(new TargetData(*TM.getTargetData()));
+ PM.add(new DataLayout(*TM.getDataLayout()));
// Turn the machine code intermediate representation into bytes in memory
// that may be executed.
@@ -370,7 +370,7 @@ bool JIT::removeModule(Module *M) {
jitstate = new JITState(Modules[0]);
FunctionPassManager &PM = jitstate->getPM(locked);
- PM.add(new TargetData(*TM.getTargetData()));
+ PM.add(new DataLayout(*TM.getDataLayout()));
// Turn the machine code intermediate representation into bytes in memory
// that may be executed.
@@ -815,8 +815,8 @@ char* JIT::getMemoryForGV(const GlobalVariable* GV) {
// through the memory manager which puts them near the code but not in the
// same buffer.
Type *GlobalType = GV->getType()->getElementType();
- size_t S = getTargetData()->getTypeAllocSize(GlobalType);
- size_t A = getTargetData()->getPreferredAlignment(GV);
+ size_t S = getDataLayout()->getTypeAllocSize(GlobalType);
+ size_t A = getDataLayout()->getPreferredAlignment(GV);
if (GV->isThreadLocal()) {
MutexGuard locked(lock);
Ptr = TJI.allocateThreadLocalMemory(S);
diff --git a/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp b/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
index 42a136e72d..19c197903a 100644
--- a/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp
@@ -24,7 +24,7 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetMachine.h"
@@ -42,7 +42,7 @@ unsigned char* JITDwarfEmitter::EmitDwarfTable(MachineFunction& F,
assert(MMI && "MachineModuleInfo not registered!");
const TargetMachine& TM = F.getTarget();
- TD = TM.getTargetData();
+ TD = TM.getDataLayout();
stackGrowthDirection = TM.getFrameLowering()->getStackGrowthDirection();
RI = TM.getRegisterInfo();
MAI = TM.getMCAsmInfo();
diff --git a/lib/ExecutionEngine/JIT/JITDwarfEmitter.h b/lib/ExecutionEngine/JIT/JITDwarfEmitter.h
index 8dc99abc42..9cdbeac86a 100644
--- a/lib/ExecutionEngine/JIT/JITDwarfEmitter.h
+++ b/lib/ExecutionEngine/JIT/JITDwarfEmitter.h
@@ -23,12 +23,12 @@ class MachineFunction;
class MachineModuleInfo;
class MachineMove;
class MCAsmInfo;
-class TargetData;
+class DataLayout;
class TargetMachine;
class TargetRegisterInfo;
class JITDwarfEmitter {
- const TargetData* TD;
+ const DataLayout* TD;
JITCodeEmitter* JCE;
const TargetRegisterInfo* RI;
const MCAsmInfo *MAI;
diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp
index b19fc6fa97..352b1e8bad 100644
--- a/lib/ExecutionEngine/JIT/JITEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp
@@ -31,7 +31,7 @@
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/ExecutionEngine/NaClJITMemoryManager.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetJITInfo.h"
#include "llvm/Target/TargetMachine.h"
@@ -1121,7 +1121,7 @@ void JITEmitter::processDebugLoc(DebugLoc DL, bool BeforePrintingInsn) {
}
static unsigned GetConstantPoolSizeInBytes(MachineConstantPool *MCP,
- const TargetData *TD) {
+ const DataLayout *TD) {
const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants();
if (Constants.empty()) return 0;
@@ -1423,7 +1423,7 @@ void JITEmitter::emitConstantPool(MachineConstantPool *MCP) {
const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants();
if (Constants.empty()) return;
- unsigned Size = GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData());
+ unsigned Size = GetConstantPoolSizeInBytes(MCP, TheJIT->getDataLayout());
unsigned Align = MCP->getConstantPoolAlignment();
ConstantPoolBase = allocateSpace(Size, Align);
ConstantPool = MCP;
@@ -1452,7 +1452,7 @@ void JITEmitter::emitConstantPool(MachineConstantPool *MCP) {
dbgs().write_hex(CAddr) << "]\n");
Type *Ty = CPE.Val.ConstVal->getType();
- Offset += TheJIT->getTargetData()->getTypeAllocSize(Ty);
+ Offset += TheJIT->getDataLayout()->getTypeAllocSize(Ty);
}
}
@@ -1469,14 +1469,14 @@ void JITEmitter::initJumpTableInfo(MachineJumpTableInfo *MJTI) {
for (unsigned i = 0, e = JT.size(); i != e; ++i)
NumEntries += JT[i].MBBs.size();
- unsigned EntrySize = MJTI->getEntrySize(*TheJIT->getTargetData());
+ unsigned EntrySize = MJTI->getEntrySize(*TheJIT->getDataLayout());
// Just allocate space for all the jump tables now. We will fix up the actual
// MBB entries in the tables after we emit the code for each block, since then
// we will know the final locations of the MBBs in memory.
JumpTable = MJTI;
JumpTableBase = allocateSpace(NumEntries * EntrySize,
- MJTI->getEntryAlignment(*TheJIT->getTargetData()));
+ MJTI->getEntryAlignment(*TheJIT->getDataLayout()));
}
void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
@@ -1493,7 +1493,7 @@ void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
case MachineJumpTableInfo::EK_BlockAddress: {
// EK_BlockAddress - Each entry is a plain address of block, e.g.:
// .word LBB123
- assert(MJTI->getEntrySize(*TheJIT->getTargetData()) == sizeof(void*) &&
+ assert(MJTI->getEntrySize(*TheJIT->getDataLayout()) == sizeof(void*) &&
"Cross JIT'ing?");
// For each jump table, map each target in the jump table to the address of
@@ -1513,7 +1513,7 @@ void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
case MachineJumpTableInfo::EK_Custom32:
case MachineJumpTableInfo::EK_GPRel32BlockAddress:
case MachineJumpTableInfo::EK_LabelDifference32: {
- assert(MJTI->getEntrySize(*TheJIT->getTargetData()) == 4&&"Cross JIT'ing?");
+ assert(MJTI->getEntrySize(*TheJIT->getDataLayout()) == 4&&"Cross JIT'ing?");
// For each jump table, place the offset from the beginning of the table
// to the target address.
int *SlotPtr = (int*)JumpTableBase;
@@ -1589,7 +1589,7 @@ uintptr_t JITEmitter::getJumpTableEntryAddress(unsigned Index) const {
const std::vector<MachineJumpTableEntry> &JT = JumpTable->getJumpTables();
assert(Index < JT.size() && "Invalid jump table index!");
- unsigned EntrySize = JumpTable->getEntrySize(*TheJIT->getTargetData());
+ unsigned EntrySize = JumpTable->getEntrySize(*TheJIT->getDataLayout());
unsigned Offset = 0;
for (unsigned i = 0; i < Index; ++i)
diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp
index fa71305145..68c0c34f61 100644
--- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp
+++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp
@@ -12,14 +12,16 @@
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/ExecutionEngine/GenericValue.h"
-#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
+#include "llvm/ExecutionEngine/MCJIT.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MutexGuard.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
using namespace llvm;
@@ -50,9 +52,9 @@ ExecutionEngine *MCJIT::createJIT(Module *M,
MCJIT::MCJIT(Module *m, TargetMachine *tm, RTDyldMemoryManager *MM,
bool AllocateGVsWithCode)
: ExecutionEngine(m), TM(tm), Ctx(0), MemMgr(MM), Dyld(MM),
- isCompiled(false), M(m), OS(Buffer) {
+ isCompiled(false), M(m) {
- setTargetData(TM->getTargetData());
+ setDataLayout(TM->getDataLayout());
}
MCJIT::~MCJIT() {
@@ -63,7 +65,7 @@ MCJIT::~MCJIT() {
void MCJIT::emitObject(Module *m) {
/// Currently, MCJIT only supports a single module and the module passed to
/// this function call is expected to be the contained module. The module
- /// is passed as a parameter here to prepare for multiple module support in
+ /// is passed as a parameter here to prepare for multiple module support in
/// the future.
assert(M == m);
@@ -78,32 +80,34 @@ void MCJIT::emitObject(Module *m) {
PassManager PM;
- PM.add(new TargetData(*TM->getTargetData()));
+ PM.add(new DataLayout(*TM->getDataLayout()));
+
+ // The RuntimeDyld will take ownership of this shortly
+ OwningPtr<ObjectBufferStream> Buffer(new ObjectBufferStream());
// Turn the machine code intermediate representation into bytes in memory
// that may be executed.
- if (TM->addPassesToEmitMC(PM, Ctx, OS, false)) {
+ if (TM->addPassesToEmitMC(PM, Ctx, Buffer->getOStream(), false)) {
report_fatal_error("Target does not support MC emission!");
}
// Initialize passes.
- // FIXME: When we support multiple modules, we'll want to move the code
- // gen and finalization out of the constructor here and do it more
- // on-demand as part of getPointerToFunction().
PM.run(*m);
- // Flush the output buffer so the SmallVector gets its data.
- OS.flush();
+ // Flush the output buffer to get the generated code into memory
+ Buffer->flush();
// Load the object into the dynamic linker.
- MemoryBuffer* MB = MemoryBuffer::getMemBuffer(StringRef(Buffer.data(),
- Buffer.size()),
- "", false);
- if (Dyld.loadObject(MB))
+ // handing off ownership of the buffer
+ LoadedObject.reset(Dyld.loadObject(Buffer.take()));
+ if (!LoadedObject)
report_fatal_error(Dyld.getErrorString());
// Resolve any relocations.
Dyld.resolveRelocations();
+ // FIXME: Make this optional, maybe even move it to a JIT event listener
+ LoadedObject->registerWithDebugger();
+
// FIXME: Add support for per-module compilation state
isCompiled = true;
}
diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.h b/lib/ExecutionEngine/MCJIT/MCJIT.h
index d5c5d77574..b9ff06e701 100644
--- a/lib/ExecutionEngine/MCJIT/MCJIT.h
+++ b/lib/ExecutionEngine/MCJIT/MCJIT.h
@@ -13,11 +13,11 @@
#include "llvm/PassManager.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/raw_ostream.h"
namespace llvm {
+class ObjectImage;
+
// FIXME: This makes all kinds of horrible assumptions for the time being,
// like only having one module, not needing to worry about multi-threading,
// blah blah. Purely in get-it-up-and-limping mode for now.
@@ -34,10 +34,7 @@ class MCJIT : public ExecutionEngine {
// FIXME: Add support for multiple modules
bool isCompiled;
Module *M;
-
- // FIXME: Move these to a single container which manages JITed objects
- SmallVector<char, 4096> Buffer; // Working buffer into which we JIT.
- raw_svector_ostream OS;
+ OwningPtr<ObjectImage> LoadedObject;
public:
~MCJIT();
diff --git a/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp b/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
index 8b50101422..50cd0724ea 100644
--- a/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp
@@ -78,12 +78,12 @@ public:
/// Creates an entry in the JIT registry for the buffer @p Object,
/// which must contain an object file in executable memory with any
/// debug information for the debugger.
- void registerObject(const MemoryBuffer &Object);
+ void registerObject(const ObjectBuffer &Object);
/// Removes the internal registration of @p Object, and
/// frees associated resources.
/// Returns true if @p Object was found in ObjectBufferMap.
- bool deregisterObject(const MemoryBuffer &Object);
+ bool deregisterObject(const ObjectBuffer &Object);
private:
/// Deregister the debug info for the given object file from the debugger
@@ -124,7 +124,7 @@ GDBJITRegistrar::~GDBJITRegistrar() {
ObjectBufferMap.clear();
}
-void GDBJITRegistrar::registerObject(const MemoryBuffer &Object) {
+void GDBJITRegistrar::registerObject(const ObjectBuffer &Object) {
const char *Buffer = Object.getBufferStart();
size_t Size = Object.getBufferSize();
@@ -147,7 +147,7 @@ void GDBJITRegistrar::registerObject(const MemoryBuffer &Object) {
}
}
-bool GDBJITRegistrar::deregisterObject(const MemoryBuffer& Object) {
+bool GDBJITRegistrar::deregisterObject(const ObjectBuffer& Object) {
const char *Buffer = Object.getBufferStart();
RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(Buffer);
diff --git a/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h b/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h
index f964bc6182..69e9dbe490 100644
--- a/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h
+++ b/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h
@@ -10,7 +10,7 @@
#ifndef LLVM_EXECUTION_ENGINE_JIT_REGISTRAR_H
#define LLVM_EXECUTION_ENGINE_JIT_REGISTRAR_H
-#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
namespace llvm {
@@ -27,12 +27,12 @@ public:
/// Creates an entry in the JIT registry for the buffer @p Object,
/// which must contain an object file in executable memory with any
/// debug information for the debugger.
- virtual void registerObject(const MemoryBuffer &Object) = 0;
+ virtual void registerObject(const ObjectBuffer &Object) = 0;
/// Removes the internal registration of @p Object, and
/// frees associated resources.
/// Returns true if @p Object was previously registered.
- virtual bool deregisterObject(const MemoryBuffer &Object) = 0;
+ virtual bool deregisterObject(const ObjectBuffer &Object) = 0;
/// Returns a reference to a GDB JIT registrar singleton
static JITRegistrar& getGDBRegistrar();
diff --git a/lib/ExecutionEngine/RuntimeDyld/ObjectImage.h b/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
index 4fa5c1cfea..17f3a21464 100644
--- a/lib/ExecutionEngine/RuntimeDyld/ObjectImage.h
+++ b/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h
@@ -1,59 +1,76 @@
-//===---- ObjectImage.h - Format independent executuable object image -----===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares a file format independent ObjectImage class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H
-#define LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H
-
-#include "llvm/Object/ObjectFile.h"
-
-namespace llvm {
-
-class ObjectImage {
- ObjectImage() LLVM_DELETED_FUNCTION;
- ObjectImage(const ObjectImage &other) LLVM_DELETED_FUNCTION;
-protected:
- object::ObjectFile *ObjFile;
-
-public:
- ObjectImage(object::ObjectFile *Obj) { ObjFile = Obj; }
- virtual ~ObjectImage() {}
-
- virtual object::symbol_iterator begin_symbols() const
- { return ObjFile->begin_symbols(); }
- virtual object::symbol_iterator end_symbols() const
- { return ObjFile->end_symbols(); }
-
- virtual object::section_iterator begin_sections() const
- { return ObjFile->begin_sections(); }
- virtual object::section_iterator end_sections() const
- { return ObjFile->end_sections(); }
-
- virtual /* Triple::ArchType */ unsigned getArch() const
- { return ObjFile->getArch(); }
-
- // Subclasses can override these methods to update the image with loaded
- // addresses for sections and common symbols
- virtual void updateSectionAddress(const object::SectionRef &Sec,
- uint64_t Addr) {}
- virtual void updateSymbolAddress(const object::SymbolRef &Sym, uint64_t Addr)
- {}
-
- // Subclasses can override these methods to provide JIT debugging support
- virtual void registerWithDebugger() {}
- virtual void deregisterWithDebugger() {}
-};
-
-} // end namespace llvm
-
-#endif // LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H
-
+//===-- ObjectImageCommon.h - Format independent executuable object image -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a file format independent ObjectImage class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_RUNTIMEDYLD_OBJECTIMAGECOMMON_H
+#define LLVM_RUNTIMEDYLD_OBJECTIMAGECOMMON_H
+
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
+
+namespace llvm {
+
+class ObjectImageCommon : public ObjectImage {
+ ObjectImageCommon(); // = delete
+ ObjectImageCommon(const ObjectImageCommon &other); // = delete
+
+protected:
+ object::ObjectFile *ObjFile;
+
+ // This form of the constructor allows subclasses to use
+ // format-specific subclasses of ObjectFile directly
+ ObjectImageCommon(ObjectBuffer *Input, object::ObjectFile *Obj)
+ : ObjectImage(Input), // saves Input as Buffer and takes ownership
+ ObjFile(Obj)
+ {
+ }
+
+public:
+ ObjectImageCommon(ObjectBuffer* Input)
+ : ObjectImage(Input) // saves Input as Buffer and takes ownership
+ {
+ ObjFile = object::ObjectFile::createObjectFile(Buffer->getMemBuffer());
+ }
+ virtual ~ObjectImageCommon() { delete ObjFile; }
+
+ virtual object::symbol_iterator begin_symbols() const
+ { return ObjFile->begin_symbols(); }
+ virtual object::symbol_iterator end_symbols() const
+ { return ObjFile->end_symbols(); }
+
+ virtual object::section_iterator begin_sections() const
+ { return ObjFile->begin_sections(); }
+ virtual object::section_iterator end_sections() const
+ { return ObjFile->end_sections(); }
+
+ virtual /* Triple::ArchType */ unsigned getArch() const
+ { return ObjFile->getArch(); }
+
+ virtual StringRef getData() const { return ObjFile->getData(); }
+
+ // Subclasses can override these methods to update the image with loaded
+ // addresses for sections and common symbols
+ virtual void updateSectionAddress(const object::SectionRef &Sec,
+ uint64_t Addr) {}
+ virtual void updateSymbolAddress(const object::SymbolRef &Sym, uint64_t Addr)
+ {}
+
+ // Subclasses can override these methods to provide JIT debugging support
+ virtual void registerWithDebugger() {}
+ virtual void deregisterWithDebugger() {}
+};
+
+} // end namespace llvm
+
+#endif // LLVM_RUNTIMEDYLD_OBJECT_IMAGE_H
+
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
index d06a1fc984..eb69693359 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "dyld"
+#include "ObjectImageCommon.h"
#include "RuntimeDyldImpl.h"
#include "RuntimeDyldELF.h"
#include "RuntimeDyldMachO.h"
@@ -61,14 +62,11 @@ void RuntimeDyldImpl::mapSectionAddress(const void *LocalAddress,
// Subclasses can implement this method to create specialized image instances.
// The caller owns the pointer that is returned.
-ObjectImage *RuntimeDyldImpl::createObjectImage(const MemoryBuffer *InputBuffer) {
- ObjectFile *ObjFile = ObjectFile::createObjectFile(const_cast<MemoryBuffer*>
- (InputBuffer));
- ObjectImage *Obj = new ObjectImage(ObjFile);
- return Obj;
+ObjectImage *RuntimeDyldImpl::createObjectImage(ObjectBuffer *InputBuffer) {
+ return new ObjectImageCommon(InputBuffer);
}
-bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) {
+ObjectImage *RuntimeDyldImpl::loadObject(ObjectBuffer *InputBuffer) {
OwningPtr<ObjectImage> obj(createObjectImage(InputBuffer));
if (!obj)
report_fatal_error("Unable to create object image from memory buffer!");
@@ -178,9 +176,7 @@ bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) {
}
}
- handleObjectLoaded(obj.take());
-
- return false;
+ return obj.take();
}
void RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj,
@@ -437,7 +433,7 @@ RuntimeDyld::~RuntimeDyld() {
delete Dyld;
}
-bool RuntimeDyld::loadObject(MemoryBuffer *InputBuffer) {
+ObjectImage *RuntimeDyld::loadObject(ObjectBuffer *InputBuffer) {
if (!Dyld) {
sys::LLVMFileType type = sys::IdentifyFileType(
InputBuffer->getBufferStart(),
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index a1c0e4020f..efefacf632 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -12,16 +12,19 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "dyld"
+#include "RuntimeDyldELF.h"
+#include "JITRegistrar.h"
+#include "ObjectImageCommon.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/IntervalMap.h"
-#include "RuntimeDyldELF.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
#include "llvm/Support/ELF.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Object/ELF.h"
-#include "JITRegistrar.h"
using namespace llvm;
using namespace llvm::object;
@@ -41,19 +44,12 @@ class DyldELFObject : public ELFObjectFile<target_endianness, is64Bits> {
typedef typename ELFDataTypeTypedefHelper<
target_endianness, is64Bits>::value_type addr_type;
-protected:
- // This duplicates the 'Data' member in the 'Binary' base class
- // but it is necessary to workaround a bug in gcc 4.2
- MemoryBuffer *InputData;
-
public:
- DyldELFObject(MemoryBuffer *Object, error_code &ec);
+ DyldELFObject(MemoryBuffer *Wrapper, error_code &ec);
void updateSectionAddress(const SectionRef &Sec, uint64_t Addr);
void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr);
- const MemoryBuffer& getBuffer() const { return *InputData; }
-
// Methods for type inquiry through isa, cast and dyn_cast
static inline bool classof(const Binary *v) {
return (isa<ELFObjectFile<target_endianness, is64Bits> >(v)
@@ -69,14 +65,15 @@ public:
};
template<support::endianness target_endianness, bool is64Bits>
-class ELFObjectImage : public ObjectImage {
+class ELFObjectImage : public ObjectImageCommon {
protected:
DyldELFObject<target_endianness, is64Bits> *DyldObj;
bool Registered;
public:
- ELFObjectImage(DyldELFObject<target_endianness, is64Bits> *Obj)
- : ObjectImage(Obj),
+ ELFObjectImage(ObjectBuffer *Input,
+ DyldELFObject<target_endianness, is64Bits> *Obj)
+ : ObjectImageCommon(Input, Obj),
DyldObj(Obj),
Registered(false) {}
@@ -99,20 +96,22 @@ class ELFObjectImage : public ObjectImage {
virtual void registerWithDebugger()
{
- JITRegistrar::getGDBRegistrar().registerObject(DyldObj->getBuffer());
+ JITRegistrar::getGDBRegistrar().registerObject(*Buffer);
Registered = true;
}
virtual void deregisterWithDebugger()
{
- JITRegistrar::getGDBRegistrar().deregisterObject(DyldObj->getBuffer());
+ JITRegistrar::getGDBRegistrar().deregisterObject(*Buffer);
}
};
+// The MemoryBuffer passed into this constructor is just a wrapper around the
+// actual memory. Ultimately, the Binary parent class will take ownership of
+// this MemoryBuffer object but not the underlying memory.
template<support::endianness target_endianness, bool is64Bits>
-DyldELFObject<target_endianness, is64Bits>::DyldELFObject(MemoryBuffer *Object,
+DyldELFObject<target_endianness, is64Bits>::DyldELFObject(MemoryBuffer *Wrapper,
error_code &ec)
- : ELFObjectFile<target_endianness, is64Bits>(Object, ec),
- InputData(Object) {
+ : ELFObjectFile<target_endianness, is64Bits>(Wrapper, ec) {
this->isDyldELFObject = true;
}
@@ -148,46 +147,39 @@ void DyldELFObject<target_endianness, is64Bits>::updateSymbolAddress(
namespace llvm {
-ObjectImage *RuntimeDyldELF::createObjectImage(
- const MemoryBuffer *ConstInputBuffer) {
- MemoryBuffer *InputBuffer = const_cast<MemoryBuffer*>(ConstInputBuffer);
- std::pair<unsigned char, unsigned char> Ident = getElfArchType(InputBuffer);
+ObjectImage *RuntimeDyldELF::createObjectImage(ObjectBuffer *Buffer) {
+ if (Buffer->getBufferSize() < ELF::EI_NIDENT)
+ llvm_unreachable("Unexpected ELF object size");
+ std::pair<unsigned char, unsigned char> Ident = std::make_pair(
+ (uint8_t)Buffer->getBufferStart()[ELF::EI_CLASS],
+ (uint8_t)Buffer->getBufferStart()[ELF::EI_DATA]);
error_code ec;
if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) {
DyldELFObject<support::little, false> *Obj =
- new DyldELFObject<support::little, false>(InputBuffer, ec);
- return new ELFObjectImage<support::little, false>(Obj);
+ new DyldELFObject<support::little, false>(Buffer->getMemBuffer(), ec);
+ return new ELFObjectImage<support::little, false>(Buffer, Obj);
}
else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB) {
DyldELFObject<support::big, false> *Obj =
- new DyldELFObject<support::big, false>(InputBuffer, ec);
- return new ELFObjectImage<support::big, false>(Obj);
+ new DyldELFObject<support::big, false>(Buffer->getMemBuffer(), ec);
+ return new ELFObjectImage<support::big, false>(Buffer, Obj);
}
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB) {
DyldELFObject<support::big, true> *Obj =
- new DyldELFObject<support::big, true>(InputBuffer, ec);
- return new ELFObjectImage<support::big, true>(Obj);
+ new DyldELFObject<support::big, true>(Buffer->getMemBuffer(), ec);
+ return new ELFObjectImage<support::big, true>(Buffer, Obj);
}
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
DyldELFObject<support::little, true> *Obj =
- new DyldELFObject<support::little, true>(InputBuffer, ec);
- return new ELFObjectImage<support::little, true>(Obj);
+ new DyldELFObject<support::little, true>(Buffer->getMemBuffer(), ec);
+ return new ELFObjectImage<support::little, true>(Buffer, Obj);
}
else
llvm_unreachable("Unexpected ELF format");
}
-void RuntimeDyldELF::handleObjectLoaded(ObjectImage *Obj)
-{
- Obj->registerWithDebugger();
- // Save the loaded object. It will deregister itself when deleted
- LoadedObject = Obj;
-}
-
RuntimeDyldELF::~RuntimeDyldELF() {
- if (LoadedObject)
- delete LoadedObject;
}
void RuntimeDyldELF::resolveX86_64Relocation(uint8_t *LocalAddress,
@@ -272,14 +264,19 @@ void RuntimeDyldELF::resolveARMRelocation(uint8_t *LocalAddress,
default:
llvm_unreachable("Not implemented relocation type!");
- // Just write 32bit value to relocation address
+ // Write a 32bit value to relocation address, taking into account the
+ // implicit addend encoded in the target.
case ELF::R_ARM_ABS32 :
- *TargetPtr = Value;
+ *TargetPtr += Value;
break;
// Write first 16 bit of 32 bit value to the mov instruction.
// Last 4 bit should be shifted.
case ELF::R_ARM_MOVW_ABS_NC :
+ // We are not expecting any other addend in the relocation address.
+ // Using 0x000F0FFF because MOVW has its 16 bit immediate split into 2
+ // non-contiguous fields.
+ assert((*TargetPtr & 0x000F0FFF) == 0);
Value = Value & 0xFFFF;
*TargetPtr |= Value & 0xFFF;
*TargetPtr |= ((Value >> 12) & 0xF) << 16;
@@ -288,6 +285,9 @@ void RuntimeDyldELF::resolveARMRelocation(uint8_t *LocalAddress,
// Write last 16 bit of 32 bit value to the mov instruction.
// Last 4 bit should be shifted.
case ELF::R_ARM_MOVT_ABS :
+ // We are not expecting any other addend in the relocation address.
+ // Use 0x000F0FFF for the same reason as R_ARM_MOVW_ABS_NC.
+ assert((*TargetPtr & 0x000F0FFF) == 0);
Value = (Value >> 16) & 0xFFFF;
*TargetPtr |= Value & 0xFFF;
*TargetPtr |= ((Value >> 12) & 0xF) << 16;
@@ -522,8 +522,9 @@ void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel,
}
}
-bool RuntimeDyldELF::isCompatibleFormat(const MemoryBuffer *InputBuffer) const {
- StringRef Magic = InputBuffer->getBuffer().slice(0, ELF::EI_NIDENT);
- return (memcmp(Magic.data(), ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
+bool RuntimeDyldELF::isCompatibleFormat(const ObjectBuffer *Buffer) const {
+ if (Buffer->getBufferSize() < strlen(ELF::ElfMagic))
+ return false;
+ return (memcmp(Buffer->getBufferStart(), ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
}
} // namespace llvm
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
index eade49ee25..3011a06537 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
@@ -22,8 +22,6 @@ using namespace llvm;
namespace llvm {
class RuntimeDyldELF : public RuntimeDyldImpl {
protected:
- ObjectImage *LoadedObject;
-
void resolveX86_64Relocation(uint8_t *LocalAddress,
uint64_t FinalAddress,
uint64_t Value,
@@ -60,16 +58,15 @@ protected:
const SymbolTableMap &Symbols,
StubMap &Stubs);
- virtual ObjectImage *createObjectImage(const MemoryBuffer *InputBuffer);
- virtual void handleObjectLoaded(ObjectImage *Obj);
+ virtual ObjectImage *createObjectImage(ObjectBuffer *InputBuffer);
public:
RuntimeDyldELF(RTDyldMemoryManager *mm)
- : RuntimeDyldImpl(mm), LoadedObject(0) {}
+ : RuntimeDyldImpl(mm) {}
virtual ~RuntimeDyldELF();
- bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const;
+ bool isCompatibleFormat(const ObjectBuffer *Buffer) const;
};
} // end namespace llvm
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
index d56cab293c..a9733407ec 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
@@ -14,8 +14,8 @@
#ifndef LLVM_RUNTIME_DYLD_IMPL_H
#define LLVM_RUNTIME_DYLD_IMPL_H
-#include "ObjectImage.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
@@ -33,7 +33,7 @@ using namespace llvm::object;
namespace llvm {
-class MemoryBuffer;
+class ObjectBuffer;
class Twine;
@@ -251,19 +251,13 @@ protected:
/// \brief Resolve relocations to external symbols.
void resolveExternalSymbols();
- virtual ObjectImage *createObjectImage(const MemoryBuffer *InputBuffer);
- virtual void handleObjectLoaded(ObjectImage *Obj)
- {
- // Subclasses may choose to retain this image if they have a use for it
- delete Obj;
- }
-
+ virtual ObjectImage *createObjectImage(ObjectBuffer *InputBuffer);
public:
RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), HasError(false) {}
virtual ~RuntimeDyldImpl();
- bool loadObject(const MemoryBuffer *InputBuffer);
+ ObjectImage *loadObject(ObjectBuffer *InputBuffer);
void *getSymbolAddress(StringRef Name) {
// FIXME: Just look up as a function for now. Overly simple of course.
@@ -298,8 +292,7 @@ public:
// Get the error message.
StringRef getErrorString() { return ErrorStr; }
- virtual bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const = 0;
-
+ virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const = 0;
};
} // end namespace llvm
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
index 465e85d7d9..56540c23da 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
@@ -295,8 +295,10 @@ void RuntimeDyldMachO::processRelocationRef(const ObjRelocationInfo &Rel,
bool RuntimeDyldMachO::isCompatibleFormat(
- const MemoryBuffer *InputBuffer) const {
- StringRef Magic = InputBuffer->getBuffer().slice(0, 4);
+ const ObjectBuffer *InputBuffer) const {
+ if (InputBuffer->getBufferSize() < 4)
+ return false;
+ StringRef Magic(InputBuffer->getBufferStart(), 4);
if (Magic == "\xFE\xED\xFA\xCE") return true;
if (Magic == "\xCE\xFA\xED\xFE") return true;
if (Magic == "\xFE\xED\xFA\xCF") return true;
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
index 707664c732..ef56f551fc 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
@@ -63,7 +63,7 @@ public:
RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
- bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const;
+ bool isCompatibleFormat(const ObjectBuffer *Buffer) const;
};
} // end namespace llvm
diff --git a/lib/ExecutionEngine/TargetSelect.cpp b/lib/ExecutionEngine/TargetSelect.cpp
index 7cdd669028..8b6104fdca 100644
--- a/lib/ExecutionEngine/TargetSelect.cpp
+++ b/lib/ExecutionEngine/TargetSelect.cpp
@@ -26,7 +26,14 @@
using namespace llvm;
TargetMachine *EngineBuilder::selectTarget() {
- Triple TT(LLVM_HOSTTRIPLE);
+ Triple TT;
+
+ // MCJIT can generate code for remote targets, but the old JIT and Interpreter
+ // must use the host architecture.
+ if (UseMCJIT && WhichEngine != EngineKind::Interpreter && M)
+ TT.setTriple(M->getTargetTriple());
+ else
+ TT.setTriple(LLVM_HOSTTRIPLE);
return selectTarget(TT, MArch, MCPU, MAttrs);
}
diff --git a/lib/MC/MCAsmBackend.cpp b/lib/MC/MCAsmBackend.cpp
index 2e447b05a4..53960e7980 100644
--- a/lib/MC/MCAsmBackend.cpp
+++ b/lib/MC/MCAsmBackend.cpp
@@ -12,12 +12,9 @@
using namespace llvm;
MCAsmBackend::MCAsmBackend()
- : HasReliableSymbolDifference(false)
-{
-}
+ : HasReliableSymbolDifference(false), HasDataInCodeSupport(false) {}
-MCAsmBackend::~MCAsmBackend() {
-}
+MCAsmBackend::~MCAsmBackend() {}
const MCFixupKindInfo &
MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp
index d1aeaf36c7..1d28ec45cb 100644
--- a/lib/MC/MCELFStreamer.cpp
+++ b/lib/MC/MCELFStreamer.cpp
@@ -98,12 +98,6 @@ public:
uint64_t Size, unsigned ByteAlignment = 0) {
llvm_unreachable("ELF doesn't support this directive");
}
- virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
- virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
- unsigned ValueSize = 1,
- unsigned MaxBytesToEmit = 0);
- virtual void EmitCodeAlignment(unsigned ByteAlignment,
- unsigned MaxBytesToEmit = 0);
virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
unsigned AddrSpace);
@@ -355,51 +349,6 @@ void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
EmitCommonSymbol(Symbol, Size, ByteAlignment);
}
-void MCELFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
- // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
- // MCObjectStreamer.
- getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
- getCurrentSectionData()->MarkBundleOffsetUnknown(); // @LOCALMOD
-}
-
-void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment,
- int64_t Value, unsigned ValueSize,
- unsigned MaxBytesToEmit) {
- // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
- // MCObjectStreamer.
- if (MaxBytesToEmit == 0)
- MaxBytesToEmit = ByteAlignment;
- new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
- getCurrentSectionData());
-
- // @LOCALMOD-BEGIN
- // Bump the bundle offset to account for alignment.
- getCurrentSectionData()->AlignBundleOffsetTo(ByteAlignment);
- // @LOCALMOD-END
- // Update the maximum alignment on the current section if necessary.
- if (ByteAlignment > getCurrentSectionData()->getAlignment())
- getCurrentSectionData()->setAlignment(ByteAlignment);
-}
-
-void MCELFStreamer::EmitCodeAlignment(unsigned ByteAlignment,
- unsigned MaxBytesToEmit) {
- // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
- // MCObjectStreamer.
- if (MaxBytesToEmit == 0)
- MaxBytesToEmit = ByteAlignment;
- MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit,
- getCurrentSectionData());
- F->setEmitNops(true);
-
- // @LOCALMOD-BEGIN
- // Bump the bundle offset to account for alignment.
- getCurrentSectionData()->AlignBundleOffsetTo(ByteAlignment);
- // @LOCALMOD-END
- // Update the maximum alignment on the current section if necessary.
- if (ByteAlignment > getCurrentSectionData()->getAlignment())
- getCurrentSectionData()->setAlignment(ByteAlignment);
-}
-
void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
unsigned AddrSpace) {
fixSymbolsInTLSFixups(Value);
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index 74f6dc62e1..04b0e86aed 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -75,12 +75,6 @@ public:
uint64_t Size = 0, unsigned ByteAlignment = 0);
virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment = 0);
- virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
- virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
- unsigned ValueSize = 1,
- unsigned MaxBytesToEmit = 0);
- virtual void EmitCodeAlignment(unsigned ByteAlignment,
- unsigned MaxBytesToEmit = 0);
virtual void EmitFileDirective(StringRef Filename) {
// FIXME: Just ignore the .file; it isn't important enough to fail the
@@ -139,6 +133,8 @@ void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
}
void MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) {
+ if (!getAssembler().getBackend().hasDataInCodeSupport())
+ return;
// Create a temporary label to mark the start of the data region.
MCSymbol *Start = getContext().CreateTempSymbol();
EmitLabel(Start);
@@ -149,6 +145,8 @@ void MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) {
}
void MCMachOStreamer::EmitDataRegionEnd() {
+ if (!getAssembler().getBackend().hasDataInCodeSupport())
+ return;
std::vector<DataRegionData> &Regions = getAssembler().getDataRegions();
assert(Regions.size() && "Mismatched .end_data_region!");
DataRegionData &Data = Regions.back();
@@ -368,42 +366,6 @@ void MCMachOStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
return;
}
-void MCMachOStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
- // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
- // MCObjectStreamer.
- getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
-}
-
-void MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment,
- int64_t Value, unsigned ValueSize,
- unsigned MaxBytesToEmit) {
- // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
- // MCObjectStreamer.
- if (MaxBytesToEmit == 0)
- MaxBytesToEmit = ByteAlignment;
- new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
- getCurrentSectionData());
-
- // Update the maximum alignment on the current section if necessary.
- if (ByteAlignment > getCurrentSectionData()->getAlignment())
- getCurrentSectionData()->setAlignment(ByteAlignment);
-}
-
-void MCMachOStreamer::EmitCodeAlignment(unsigned ByteAlignment,
- unsigned MaxBytesToEmit) {
- // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
- // MCObjectStreamer.
- if (MaxBytesToEmit == 0)
- MaxBytesToEmit = ByteAlignment;
- MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit,
- getCurrentSectionData());
- F->setEmitNops(true);
-
- // Update the maximum alignment on the current section if necessary.
- if (ByteAlignment > getCurrentSectionData()->getAlignment())
- getCurrentSectionData()->setAlignment(ByteAlignment);
-}
-
void MCMachOStreamer::EmitInstToData(const MCInst &Inst) {
MCDataFragment *DF = getOrCreateDataFragment();
diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp
index 8053624831..2e1604d6b5 100644
--- a/lib/MC/MCObjectFileInfo.cpp
+++ b/lib/MC/MCObjectFileInfo.cpp
@@ -392,6 +392,18 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
DwarfMacroInfoSection =
Ctx->getELFSection(".debug_macinfo", ELF::SHT_PROGBITS, 0,
SectionKind::getMetadata());
+ DwarfAccelNamesSection =
+ Ctx->getELFSection(".apple_names", ELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfAccelObjCSection =
+ Ctx->getELFSection(".apple_objc", ELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfAccelNamespaceSection =
+ Ctx->getELFSection(".apple_namespaces", ELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfAccelTypesSection =
+ Ctx->getELFSection(".apple_types", ELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
}
@@ -565,6 +577,7 @@ void MCObjectFileInfo::InitMCObjectFileInfo(StringRef TT, Reloc::Model relocm,
Env = IsMachO;
InitMachOMCObjectFileInfo(T);
} else if ((Arch == Triple::x86 || Arch == Triple::x86_64) &&
+ (T.getEnvironment() != Triple::ELF) &&
(T.getOS() == Triple::MinGW32 || T.getOS() == Triple::Cygwin ||
T.getOS() == Triple::Win32)) {
Env = IsCOFF;
diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp
index c4d9e22280..6f32bf57b6 100644
--- a/lib/MC/MCObjectStreamer.cpp
+++ b/lib/MC/MCObjectStreamer.cpp
@@ -294,6 +294,36 @@ void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData());
}
+void MCObjectStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
+ assert(AddrSpace == 0 && "Address space must be 0!");
+ getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
+ getCurrentSectionData()->MarkBundleOffsetUnknown(); // @LOCALMOD
+}
+
+void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
+ int64_t Value,
+ unsigned ValueSize,
+ unsigned MaxBytesToEmit) {
+ if (MaxBytesToEmit == 0)
+ MaxBytesToEmit = ByteAlignment;
+ new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
+ getCurrentSectionData());
+
+ // @LOCALMOD-BEGIN
+ // Bump the bundle offset to account for alignment.
+ getCurrentSectionData()->AlignBundleOffsetTo(ByteAlignment);
+ // @LOCALMOD-END
+ // Update the maximum alignment on the current section if necessary.
+ if (ByteAlignment > getCurrentSectionData()->getAlignment())
+ getCurrentSectionData()->setAlignment(ByteAlignment);
+}
+
+void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit) {
+ EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
+ cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
+}
+
bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
unsigned char Value) {
int64_t Res;
@@ -332,6 +362,14 @@ void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
DF->getContents().resize(DF->getContents().size() + 8, 0);
}
+void MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
+ unsigned AddrSpace) {
+ assert(AddrSpace == 0 && "Address space must be 0!");
+ // FIXME: A MCFillFragment would be more memory efficient but MCExpr has
+ // problems evaluating expressions across multiple fragments.
+ getOrCreateDataFragment()->getContents().append(NumBytes, FillValue);
+}
+
void MCObjectStreamer::FinishImpl() {
// Dump out the dwarf file & directory tables and line tables.
const MCSymbol *LineSectionSymbol = NULL;
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index fc0bc35347..9890e510c0 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -1044,9 +1044,6 @@ bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
}
}
-
-
-
/// ParseStatement:
/// ::= EndOfStatement
/// ::= Label* Directive ...Operands... EndOfStatement
diff --git a/lib/MC/MCSubtargetInfo.cpp b/lib/MC/MCSubtargetInfo.cpp
index 8be07eed82..80a1f02ce6 100644
--- a/lib/MC/MCSubtargetInfo.cpp
+++ b/lib/MC/MCSubtargetInfo.cpp
@@ -19,7 +19,7 @@ using namespace llvm;
MCSchedModel MCSchedModel::DefaultSchedModel; // For unknown processors.
-/// ReInitMCSubtargetInfo - Set or change the CPU (optionally supplemented
+/// InitMCProcessorInfo - Set or change the CPU (optionally supplemented
/// with feature string). Recompute feature bits and scheduling model.
void
MCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef FS) {
diff --git a/lib/MC/SubtargetFeature.cpp b/lib/MC/SubtargetFeature.cpp
index e3a9d3fa52..e24514835b 100644
--- a/lib/MC/SubtargetFeature.cpp
+++ b/lib/MC/SubtargetFeature.cpp
@@ -119,14 +119,15 @@ void SubtargetFeatures::AddFeature(const StringRef String,
}
/// Find KV in array using binary search.
-template<typename T> const T *Find(const StringRef S, const T *A, size_t L) {
+const SubtargetFeatureKV *Find(const StringRef S, const SubtargetFeatureKV *A,
+ size_t L) {
// Make the lower bound element we're looking for
- T KV;
+ SubtargetFeatureKV KV;
KV.Key = S.data();
// Determine the end of the array
- const T *Hi = A + L;
+ const SubtargetFeatureKV *Hi = A + L;
// Binary search the array
- const T *F = std::lower_bound(A, Hi, KV);
+ const SubtargetFeatureKV *F = std::lower_bound(A, Hi, KV);
// If not found then return NULL
if (F == Hi || StringRef(F->Key) != S) return NULL;
// Return the found array item
@@ -336,30 +337,6 @@ uint64_t SubtargetFeatures::getFeatureBits(const StringRef CPU,
return Bits;
}
-/// Get scheduling itinerary of a CPU.
-const void *SubtargetFeatures::getItinerary(const StringRef CPU,
- const SubtargetInfoKV *Table,
- size_t TableSize) {
- assert(Table && "missing table");
-#ifndef NDEBUG
- for (size_t i = 1; i < TableSize; i++) {
- assert(strcmp(Table[i - 1].Key, Table[i].Key) < 0 && "Table is not sorted");
- }
-#endif
-
- // Find entry
- const SubtargetInfoKV *Entry = Find(CPU, Table, TableSize);
-
- if (Entry) {
- return Entry->Value;
- } else {
- errs() << "'" << CPU
- << "' is not a recognized processor for this target"
- << " (ignoring processor)\n";
- return NULL;
- }
-}
-
/// print - Print feature string.
///
void SubtargetFeatures::print(raw_ostream &OS) const {
diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp
index b026277ac6..702eec04ef 100644
--- a/lib/MC/WinCOFFStreamer.cpp
+++ b/lib/MC/WinCOFFStreamer.cpp
@@ -70,11 +70,6 @@ public:
uint64_t Size,unsigned ByteAlignment);
virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment);
- virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
- virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
- unsigned ValueSize, unsigned MaxBytesToEmit);
- virtual void EmitCodeAlignment(unsigned ByteAlignment,
- unsigned MaxBytesToEmit);
virtual void EmitFileDirective(StringRef Filename);
virtual void EmitInstruction(const MCInst &Instruction);
virtual void EmitWin64EHHandlerData();
@@ -333,43 +328,6 @@ void WinCOFFStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
llvm_unreachable("not implemented");
}
-void WinCOFFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
- // TODO: This is copied exactly from the MachOStreamer. Consider merging into
- // MCObjectStreamer?
- getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
-}
-
-void WinCOFFStreamer::EmitValueToAlignment(unsigned ByteAlignment,
- int64_t Value,
- unsigned ValueSize,
- unsigned MaxBytesToEmit) {
- // TODO: This is copied exactly from the MachOStreamer. Consider merging into
- // MCObjectStreamer?
- if (MaxBytesToEmit == 0)
- MaxBytesToEmit = ByteAlignment;
- new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
- getCurrentSectionData());
-
- // Update the maximum alignment on the current section if necessary.
- if (ByteAlignment > getCurrentSectionData()->getAlignment())
- getCurrentSectionData()->setAlignment(ByteAlignment);
-}
-
-void WinCOFFStreamer::EmitCodeAlignment(unsigned ByteAlignment,
- unsigned MaxBytesToEmit) {
- // TODO: This is copied exactly from the MachOStreamer. Consider merging into
- // MCObjectStreamer?
- if (MaxBytesToEmit == 0)
- MaxBytesToEmit = ByteAlignment;
- MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit,
- getCurrentSectionData());
- F->setEmitNops(true);
-
- // Update the maximum alignment on the current section if necessary.
- if (ByteAlignment > getCurrentSectionData()->getAlignment())
- getCurrentSectionData()->setAlignment(ByteAlignment);
-}
-
void WinCOFFStreamer::EmitFileDirective(StringRef Filename) {
// Ignore for now, linkers don't care, and proper debug
// info will be a much large effort.
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
index 593315d1a7..fc4f1891d9 100644
--- a/lib/Support/CommandLine.cpp
+++ b/lib/Support/CommandLine.cpp
@@ -464,7 +464,7 @@ static void ParseCStringVector(std::vector<char *> &OutputVector,
/// an environment variable (whose name is given in ENVVAR).
///
void cl::ParseEnvironmentOptions(const char *progName, const char *envVar,
- const char *Overview, bool ReadResponseFiles) {
+ const char *Overview) {
// Check args.
assert(progName && "Program name not specified");
assert(envVar && "Environment variable name missing");
@@ -483,7 +483,7 @@ void cl::ParseEnvironmentOptions(const char *progName, const char *envVar,
// and hand it off to ParseCommandLineOptions().
ParseCStringVector(newArgv, envValue);
int newArgc = static_cast<int>(newArgv.size());
- ParseCommandLineOptions(newArgc, &newArgv[0], Overview, ReadResponseFiles);
+ ParseCommandLineOptions(newArgc, &newArgv[0], Overview);
// Free all the strdup()ed strings.
for (std::vector<char*>::iterator i = newArgv.begin(), e = newArgv.end();
@@ -529,7 +529,7 @@ static void ExpandResponseFiles(unsigned argc, const char*const* argv,
}
void cl::ParseCommandLineOptions(int argc, const char * const *argv,
- const char *Overview, bool ReadResponseFiles) {
+ const char *Overview) {
// Process all registered options.
SmallVector<Option*, 4> PositionalOpts;
SmallVector<Option*, 4> SinkOpts;
@@ -541,12 +541,10 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
// Expand response files.
std::vector<char*> newArgv;
- if (ReadResponseFiles) {
- newArgv.push_back(strdup(argv[0]));
- ExpandResponseFiles(argc, argv, newArgv);
- argv = &newArgv[0];
- argc = static_cast<int>(newArgv.size());
- }
+ newArgv.push_back(strdup(argv[0]));
+ ExpandResponseFiles(argc, argv, newArgv);
+ argv = &newArgv[0];
+ argc = static_cast<int>(newArgv.size());
// Copy the program name into ProgName, making sure not to overflow it.
std::string ProgName = sys::path::filename(argv[0]);
@@ -839,12 +837,10 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
MoreHelp->clear();
// Free the memory allocated by ExpandResponseFiles.
- if (ReadResponseFiles) {
- // Free all the strdup()ed strings.
- for (std::vector<char*>::iterator i = newArgv.begin(), e = newArgv.end();
- i != e; ++i)
- free(*i);
- }
+ // Free all the strdup()ed strings.
+ for (std::vector<char*>::iterator i = newArgv.begin(), e = newArgv.end();
+ i != e; ++i)
+ free(*i);
// If we had an error processing our arguments, don't let the program execute
if (ErrorParsing) exit(1);
diff --git a/lib/Support/StringRef.cpp b/lib/Support/StringRef.cpp
index 8aab4b2760..f8e9208462 100644
--- a/lib/Support/StringRef.cpp
+++ b/lib/Support/StringRef.cpp
@@ -350,8 +350,8 @@ bool llvm::getAsUnsignedInteger(StringRef Str, unsigned Radix,
unsigned long long PrevResult = Result;
Result = Result*Radix+CharVal;
- // Check for overflow.
- if (Result < PrevResult)
+ // Check for overflow by shifting back and seeing if bits were lost.
+ if (Result/Radix < PrevResult)
return true;
Str = Str.substr(1);
diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp
index d1dc7c81af..abfaecc279 100644
--- a/lib/Support/Triple.cpp
+++ b/lib/Support/Triple.cpp
@@ -42,6 +42,7 @@ const char *Triple::getArchTypeName(ArchType Kind) {
case nvptx64: return "nvptx64";
case le32: return "le32";
case amdil: return "amdil";
+ case spir: return "spir";
}
llvm_unreachable("Invalid ArchType!");
@@ -83,6 +84,7 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
case nvptx64: return "nvptx";
case le32: return "le32";
case amdil: return "amdil";
+ case spir: return "spir";
}
}
@@ -140,6 +142,7 @@ const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
case EABI: return "eabi";
case MachO: return "macho";
case Android: return "android";
+ case ELF: return "elf";
}
llvm_unreachable("Invalid EnvironmentType!");
@@ -171,6 +174,7 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
.Case("nvptx64", nvptx64)
.Case("le32", le32)
.Case("amdil", amdil)
+ .Case("spir", spir)
.Default(UnknownArch);
}
@@ -202,6 +206,7 @@ Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
.Case("nvptx", Triple::nvptx)
.Case("nvptx64", Triple::nvptx64)
.Case("amdil", Triple::amdil)
+ .Case("spir", Triple::spir)
.Default(Triple::UnknownArch);
}
@@ -226,6 +231,7 @@ const char *Triple::getArchNameForAssembler() {
.Case("nvptx64", "nvptx64")
.Case("le32", "le32")
.Case("amdil", "amdil")
+ .Case("spir", "spir")
.Default(NULL);
}
@@ -260,6 +266,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Case("nvptx64", Triple::nvptx64)
.Case("le32", Triple::le32)
.Case("amdil", Triple::amdil)
+ .Case("spir", Triple::spir)
.Default(Triple::UnknownArch);
}
@@ -308,6 +315,7 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
.StartsWith("gnu", Triple::GNU)
.StartsWith("macho", Triple::MachO)
.StartsWith("android", Triple::Android)
+ .StartsWith("elf", Triple::ELF)
.Default(Triple::UnknownEnvironment);
}
@@ -670,6 +678,7 @@ void Triple::setOSAndEnvironmentName(StringRef Str) {
static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
switch (Arch) {
+ case llvm::Triple::spir:
case llvm::Triple::UnknownArch:
return 0;
@@ -726,6 +735,7 @@ Triple Triple::get32BitArchVariant() const {
break;
case Triple::amdil:
+ case Triple::spir:
case Triple::arm:
case Triple::cellspu:
case Triple::hexagon:
@@ -772,6 +782,7 @@ Triple Triple::get64BitArchVariant() const {
T.setArch(UnknownArch);
break;
+ case Triple::spir:
case Triple::mips64:
case Triple::mips64el:
case Triple::nvptx64:
diff --git a/lib/TableGen/CMakeLists.txt b/lib/TableGen/CMakeLists.txt
index ba7bf14e5d..28240f4a67 100644
--- a/lib/TableGen/CMakeLists.txt
+++ b/lib/TableGen/CMakeLists.txt
@@ -7,7 +7,6 @@ add_llvm_library(LLVMTableGen
Main.cpp
Record.cpp
StringMatcher.cpp
- TableGenAction.cpp
TableGenBackend.cpp
TGLexer.cpp
TGParser.cpp
diff --git a/lib/TableGen/Main.cpp b/lib/TableGen/Main.cpp
index 7aeef563b8..d87d175502 100644
--- a/lib/TableGen/Main.cpp
+++ b/lib/TableGen/Main.cpp
@@ -22,8 +22,8 @@
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/system_error.h"
#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Main.h"
#include "llvm/TableGen/Record.h"
-#include "llvm/TableGen/TableGenAction.h"
#include <algorithm>
#include <cstdio>
using namespace llvm;
@@ -47,9 +47,37 @@ namespace {
cl::value_desc("directory"), cl::Prefix);
}
+/// \brief Create a dependency file for `-d` option.
+///
+/// This functionality is really only for the benefit of the build system.
+/// It is similar to GCC's `-M*` family of options.
+static int createDependencyFile(const TGParser &Parser, const char *argv0) {
+ if (OutputFilename == "-") {
+ errs() << argv0 << ": the option -d must be used together with -o\n";
+ return 1;
+ }
+ std::string Error;
+ tool_output_file DepOut(DependFilename.c_str(), Error);
+ if (!Error.empty()) {
+ errs() << argv0 << ": error opening " << DependFilename
+ << ":" << Error << "\n";
+ return 1;
+ }
+ DepOut.os() << OutputFilename << ":";
+ const std::vector<std::string> &Dependencies = Parser.getDependencies();
+ for (std::vector<std::string>::const_iterator I = Dependencies.begin(),
+ E = Dependencies.end();
+ I != E; ++I) {
+ DepOut.os() << " " << (*I);
+ }
+ DepOut.os() << "\n";
+ DepOut.keep();
+ return 0;
+}
+
namespace llvm {
-int TableGenMain(char *argv0, TableGenAction &Action) {
+int TableGenMain(char *argv0, TableGenMainFn *MainFn) {
RecordKeeper Records;
try {
@@ -82,29 +110,11 @@ int TableGenMain(char *argv0, TableGenAction &Action) {
<< ":" << Error << "\n";
return 1;
}
- if (!DependFilename.empty()) {
- if (OutputFilename == "-") {
- errs() << argv0 << ": the option -d must be used together with -o\n";
- return 1;
- }
- tool_output_file DepOut(DependFilename.c_str(), Error);
- if (!Error.empty()) {
- errs() << argv0 << ": error opening " << DependFilename
- << ":" << Error << "\n";
- return 1;
- }
- DepOut.os() << OutputFilename << ":";
- const std::vector<std::string> &Dependencies = Parser.getDependencies();
- for (std::vector<std::string>::const_iterator I = Dependencies.begin(),
- E = Dependencies.end();
- I != E; ++I) {
- DepOut.os() << " " << (*I);
- }
- DepOut.os() << "\n";
- DepOut.keep();
- }
+ if (!DependFilename.empty())
+ if (int Ret = createDependencyFile(Parser, argv0))
+ return Ret;
- if (Action(Out.os(), Records))
+ if (MainFn(Out.os(), Records))
return 1;
// Declare success.
diff --git a/lib/TableGen/Record.cpp b/lib/TableGen/Record.cpp
index 9955617aa8..83f2fff931 100644
--- a/lib/TableGen/Record.cpp
+++ b/lib/TableGen/Record.cpp
@@ -113,9 +113,7 @@ Init *BitRecTy::convertValue(IntInit *II) {
Init *BitRecTy::convertValue(TypedInit *VI) {
RecTy *Ty = VI->getType();
- if (dynamic_cast<BitRecTy*>(Ty) ||
- dynamic_cast<BitsRecTy*>(Ty) ||
- dynamic_cast<IntRecTy*>(Ty))
+ if (isa<BitRecTy>(Ty) || isa<BitsRecTy>(Ty) || isa<IntRecTy>(Ty))
return VI; // Accept variable if it is already of bit type!
return 0;
}
@@ -181,7 +179,7 @@ Init *BitsRecTy::convertValue(BitsInit *BI) {
}
Init *BitsRecTy::convertValue(TypedInit *VI) {
- if (Size == 1 && dynamic_cast<BitRecTy*>(VI->getType()))
+ if (Size == 1 && isa<BitRecTy>(VI->getType()))
return BitsInit::get(VI);
if (VI->getType()->typeIsConvertibleTo(this)) {
@@ -243,7 +241,7 @@ Init *StringRecTy::convertValue(BinOpInit *BO) {
Init *StringRecTy::convertValue(TypedInit *TI) {
- if (dynamic_cast<StringRecTy*>(TI->getType()))
+ if (isa<StringRecTy>(TI->getType()))
return TI; // Accept variable if already of the right type!
return 0;
}
@@ -263,17 +261,15 @@ Init *ListRecTy::convertValue(ListInit *LI) {
else
return 0;
- ListRecTy *LType = dynamic_cast<ListRecTy*>(LI->getType());
- if (LType == 0) {
+ if (!isa<ListRecTy>(LI->getType()))
return 0;
- }
return ListInit::get(Elements, this);
}
Init *ListRecTy::convertValue(TypedInit *TI) {
// Ensure that TI is compatible with our class.
- if (ListRecTy *LRT = dynamic_cast<ListRecTy*>(TI->getType()))
+ if (ListRecTy *LRT = dyn_cast<ListRecTy>(TI->getType()))
if (LRT->getElementType()->typeIsConvertibleTo(getElementType()))
return TI;
return 0;
@@ -309,7 +305,7 @@ Init *DagRecTy::convertValue(BinOpInit *BO) {
}
RecordRecTy *RecordRecTy::get(Record *R) {
- return &dynamic_cast<RecordRecTy&>(*R->getDefInit()->getType());
+ return dyn_cast<RecordRecTy>(R->getDefInit()->getType());
}
std::string RecordRecTy::getAsString() const {
@@ -325,7 +321,7 @@ Init *RecordRecTy::convertValue(DefInit *DI) {
Init *RecordRecTy::convertValue(TypedInit *TI) {
// Ensure that TI is compatible with Rec.
- if (RecordRecTy *RRT = dynamic_cast<RecordRecTy*>(TI->getType()))
+ if (RecordRecTy *RRT = dyn_cast<RecordRecTy>(TI->getType()))
if (RRT->getRecord()->isSubClassOf(getRecord()) ||
RRT->getRecord() == getRecord())
return TI;
@@ -354,7 +350,7 @@ RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
return T1;
// If one is a Record type, check superclasses
- if (RecordRecTy *RecTy1 = dynamic_cast<RecordRecTy*>(T1)) {
+ if (RecordRecTy *RecTy1 = dyn_cast<RecordRecTy>(T1)) {
// See if T2 inherits from a type T1 also inherits from
const std::vector<Record *> &T1SuperClasses =
RecTy1->getRecord()->getSuperClasses();
@@ -372,7 +368,7 @@ RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
}
}
}
- if (RecordRecTy *RecTy2 = dynamic_cast<RecordRecTy*>(T2)) {
+ if (RecordRecTy *RecTy2 = dyn_cast<RecordRecTy>(T2)) {
// See if T1 inherits from a type T2 also inherits from
const std::vector<Record *> &T2SuperClasses =
RecTy2->getRecord()->getSuperClasses();
@@ -599,7 +595,7 @@ ListInit *ListInit::get(ArrayRef<Init *> Range, RecTy *EltTy) {
}
void ListInit::Profile(FoldingSetNodeID &ID) const {
- ListRecTy *ListType = dynamic_cast<ListRecTy *>(getType());
+ ListRecTy *ListType = dyn_cast<ListRecTy>(getType());
assert(ListType && "Bad type for ListInit!");
RecTy *EltTy = ListType->getElementType();
@@ -1039,9 +1035,6 @@ static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
DagInit *MHSd = dynamic_cast<DagInit*>(MHS);
ListInit *MHSl = dynamic_cast<ListInit*>(MHS);
- DagRecTy *DagType = dynamic_cast<DagRecTy*>(Type);
- ListRecTy *ListType = dynamic_cast<ListRecTy*>(Type);
-
OpInit *RHSo = dynamic_cast<OpInit*>(RHS);
if (!RHSo) {
@@ -1054,7 +1047,7 @@ static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
throw TGError(CurRec->getLoc(), "!foreach requires typed variable\n");
}
- if ((MHSd && DagType) || (MHSl && ListType)) {
+ if ((MHSd && isa<DagRecTy>(Type)) || (MHSl && isa<ListRecTy>(Type))) {
if (MHSd) {
Init *Val = MHSd->getOperator();
Init *Result = EvaluateOperation(RHSo, LHS, Val,
@@ -1235,19 +1228,15 @@ std::string TernOpInit::getAsString() const {
}
RecTy *TypedInit::getFieldType(const std::string &FieldName) const {
- RecordRecTy *RecordType = dynamic_cast<RecordRecTy *>(getType());
- if (RecordType) {
- RecordVal *Field = RecordType->getRecord()->getValue(FieldName);
- if (Field) {
+ if (RecordRecTy *RecordType = dyn_cast<RecordRecTy>(getType()))
+ if (RecordVal *Field = RecordType->getRecord()->getValue(FieldName))
return Field->getType();
- }
- }
return 0;
}
Init *
TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
- BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType());
+ BitsRecTy *T = dyn_cast<BitsRecTy>(getType());
if (T == 0) return 0; // Cannot subscript a non-bits variable.
unsigned NumBits = T->getNumBits();
@@ -1263,7 +1252,7 @@ TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
Init *
TypedInit::convertInitListSlice(const std::vector<unsigned> &Elements) const {
- ListRecTy *T = dynamic_cast<ListRecTy*>(getType());
+ ListRecTy *T = dyn_cast<ListRecTy>(getType());
if (T == 0) return 0; // Cannot subscript a non-list variable.
if (Elements.size() == 1)
@@ -1336,7 +1325,7 @@ Init *VarInit::resolveListElementReference(Record &R,
RecTy *VarInit::getFieldType(const std::string &FieldName) const {
- if (RecordRecTy *RTy = dynamic_cast<RecordRecTy*>(getType()))
+ if (RecordRecTy *RTy = dyn_cast<RecordRecTy>(getType()))
if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName))
return RV->getType();
return 0;
@@ -1344,7 +1333,7 @@ RecTy *VarInit::getFieldType(const std::string &FieldName) const {
Init *VarInit::getFieldInit(Record &R, const RecordVal *RV,
const std::string &FieldName) const {
- if (dynamic_cast<RecordRecTy*>(getType()))
+ if (isa<RecordRecTy>(getType()))
if (const RecordVal *Val = R.getValue(VarName)) {
if (RV != Val && (RV || dynamic_cast<UnsetInit*>(Val->getValue())))
return 0;
@@ -1655,9 +1644,8 @@ void Record::checkName() {
const TypedInit *TypedName = dynamic_cast<const TypedInit *>(Name);
assert(TypedName && "Record name is not typed!");
RecTy *Type = TypedName->getType();
- if (dynamic_cast<StringRecTy *>(Type) == 0) {
+ if (!isa<StringRecTy>(Type))
throw TGError(getLoc(), "Record name is not a string!");
- }
}
DefInit *Record::getDefInit() {
diff --git a/lib/TableGen/TGParser.cpp b/lib/TableGen/TGParser.cpp
index aee93e7696..0ed75f014e 100644
--- a/lib/TableGen/TGParser.cpp
+++ b/lib/TableGen/TGParser.cpp
@@ -110,7 +110,6 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName,
// Convert the incoming value to a bits type of the appropriate size...
Init *BI = V->convertInitializerTo(BitsRecTy::get(BitList.size()));
if (BI == 0) {
- V->convertInitializerTo(BitsRecTy::get(BitList.size()));
return Error(Loc, "Initializer is not compatible with bit range");
}
@@ -864,8 +863,8 @@ Init *TGParser::ParseOperation(Record *CurRec) {
return 0;
}
if (LHSt) {
- ListRecTy *LType = dynamic_cast<ListRecTy*>(LHSt->getType());
- StringRecTy *SType = dynamic_cast<StringRecTy*>(LHSt->getType());
+ ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType());
+ StringRecTy *SType = dyn_cast<StringRecTy>(LHSt->getType());
if (LType == 0 && SType == 0) {
TokError("expected list or string type argumnet in unary operator");
return 0;
@@ -897,7 +896,7 @@ Init *TGParser::ParseOperation(Record *CurRec) {
}
} else {
assert(LHSt && "expected list type argument in unary operator");
- ListRecTy *LType = dynamic_cast<ListRecTy*>(LHSt->getType());
+ ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType());
if (LType == 0) {
TokError("expected list type argumnet in unary operator");
return 0;
@@ -1271,7 +1270,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
ListRecTy *GivenListTy = 0;
if (ItemType != 0) {
- ListRecTy *ListType = dynamic_cast<ListRecTy*>(ItemType);
+ ListRecTy *ListType = dyn_cast<ListRecTy>(ItemType);
if (ListType == 0) {
std::stringstream s;
s << "Type mismatch for list, expected list type, got "
@@ -1723,7 +1722,7 @@ VarInit *TGParser::ParseForeachDeclaration(ListInit *&ForeachListValue) {
return 0;
}
RecTy *ValueType = ForeachListValue->getType();
- ListRecTy *ListType = dynamic_cast<ListRecTy *>(ValueType);
+ ListRecTy *ListType = dyn_cast<ListRecTy>(ValueType);
if (ListType == 0) {
TokError("Value list is not of list type");
return 0;
diff --git a/lib/TableGen/TGParser.h b/lib/TableGen/TGParser.h
index 3d2c72cf77..9c2ad43c42 100644
--- a/lib/TableGen/TGParser.h
+++ b/lib/TableGen/TGParser.h
@@ -30,7 +30,7 @@ namespace llvm {
struct MultiClass;
struct SubClassReference;
struct SubMultiClassReference;
-
+
struct LetRecord {
std::string Name;
std::vector<unsigned> Bits;
@@ -41,7 +41,7 @@ namespace llvm {
: Name(N), Bits(B), Value(V), Loc(L) {
}
};
-
+
/// ForeachLoop - Record the iteration state associated with a for loop.
/// This is used to instantiate items in the loop body.
struct ForeachLoop {
@@ -56,13 +56,13 @@ class TGParser {
TGLexer Lex;
std::vector<std::vector<LetRecord> > LetStack;
std::map<std::string, MultiClass*> MultiClasses;
-
+
/// Loops - Keep track of any foreach loops we are within.
///
typedef std::vector<ForeachLoop> LoopVector;
LoopVector Loops;
- /// CurMultiClass - If we are parsing a 'multiclass' definition, this is the
+ /// CurMultiClass - If we are parsing a 'multiclass' definition, this is the
/// current value.
MultiClass *CurMultiClass;
@@ -82,13 +82,13 @@ class TGParser {
};
public:
- TGParser(SourceMgr &SrcMgr, RecordKeeper &records) :
+ TGParser(SourceMgr &SrcMgr, RecordKeeper &records) :
Lex(SrcMgr), CurMultiClass(0), Records(records) {}
-
+
/// ParseFile - Main entrypoint for parsing a tblgen file. These parser
/// routines return true on error, or false on success.
bool ParseFile();
-
+
bool Error(SMLoc L, const Twine &Msg) const {
PrintError(L, Msg);
return true;
@@ -102,9 +102,9 @@ public:
private: // Semantic analysis methods.
bool AddValue(Record *TheRec, SMLoc Loc, const RecordVal &RV);
- bool SetValue(Record *TheRec, SMLoc Loc, Init *ValName,
+ bool SetValue(Record *TheRec, SMLoc Loc, Init *ValName,
const std::vector<unsigned> &BitList, Init *V);
- bool SetValue(Record *TheRec, SMLoc Loc, const std::string &ValName,
+ bool SetValue(Record *TheRec, SMLoc Loc, const std::string &ValName,
const std::vector<unsigned> &BitList, Init *V) {
return SetValue(TheRec, Loc, StringInit::get(ValName), BitList, V);
}
@@ -170,7 +170,8 @@ private: // Parser methods.
IDParseMode Mode = ParseValueMode);
Init *ParseValue(Record *CurRec, RecTy *ItemType = 0,
IDParseMode Mode = ParseValueMode);
- std::vector<Init*> ParseValueList(Record *CurRec, Record *ArgsRec = 0, RecTy *EltTy = 0);
+ std::vector<Init*> ParseValueList(Record *CurRec, Record *ArgsRec = 0,
+ RecTy *EltTy = 0);
std::vector<std::pair<llvm::Init*, std::string> > ParseDagArgList(Record *);
bool ParseOptionalRangeList(std::vector<unsigned> &Ranges);
bool ParseOptionalBitList(std::vector<unsigned> &Ranges);
@@ -184,7 +185,7 @@ private: // Parser methods.
MultiClass *ParseMultiClassID();
Record *ParseDefmID();
};
-
+
} // end namespace llvm
#endif
diff --git a/lib/TableGen/TableGenAction.cpp b/lib/TableGen/TableGenAction.cpp
deleted file mode 100644
index 54e5083094..0000000000
--- a/lib/TableGen/TableGenAction.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-//===- TableGenAction.cpp - defines TableGenAction --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/TableGen/TableGenAction.h"
-
-using namespace llvm;
-
-void TableGenAction::anchor() { }
-
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp
index 95caf529d6..b8cc207ce8 100644
--- a/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -23,6 +23,8 @@
#include "InstPrinter/ARMInstPrinter.h"
#include "MCTargetDesc/ARMAddressingModes.h"
#include "MCTargetDesc/ARMMCExpr.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/Constants.h"
#include "llvm/DebugInfo.h"
#include "llvm/Module.h"
@@ -40,9 +42,8 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/ADT/SmallString.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -389,7 +390,7 @@ void ARMAsmPrinter::EmitFunctionEntryLabel() {
}
void ARMAsmPrinter::EmitXXStructor(const Constant *CV) {
- uint64_t Size = TM.getTargetData()->getTypeAllocSize(CV->getType());
+ uint64_t Size = TM.getDataLayout()->getTypeAllocSize(CV->getType());
assert(Size && "C++ constructor pointer had zero size!");
const GlobalValue *GV = dyn_cast<GlobalValue>(CV->stripPointerCasts());
@@ -482,16 +483,6 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
MCSymbol *ARMAsmPrinter::
-GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
- const MachineBasicBlock *MBB) const {
- SmallString<60> Name;
- raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
- << getFunctionNumber() << '_' << uid << '_' << uid2
- << "_set_" << MBB->getNumber();
- return OutContext.GetOrCreateSymbol(Name.str());
-}
-
-MCSymbol *ARMAsmPrinter::
GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
SmallString<60> Name;
raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
@@ -687,9 +678,24 @@ void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
const TargetLoweringObjectFileMachO &TLOFMacho =
static_cast<const TargetLoweringObjectFileMachO &>(
getObjFileLowering());
- OutStreamer.SwitchSection(TLOFMacho.getTextSection());
- OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
- OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection());
+
+ // Collect the set of sections our functions will go into.
+ SetVector<const MCSection *, SmallVector<const MCSection *, 8>,
+ SmallPtrSet<const MCSection *, 8> > TextSections;
+ // Default text section comes first.
+ TextSections.insert(TLOFMacho.getTextSection());
+ // Now any user defined text sections from function attributes.
+ for (Module::iterator F = M.begin(), e = M.end(); F != e; ++F)
+ if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage())
+ TextSections.insert(TLOFMacho.SectionForGlobal(F, Mang, TM));
+ // Now the coalescable sections.
+ TextSections.insert(TLOFMacho.getTextCoalSection());
+ TextSections.insert(TLOFMacho.getConstTextCoalSection());
+
+ // Emit the sections in the .s file header to fix the order.
+ for (unsigned i = 0, e = TextSections.size(); i != e; ++i)
+ OutStreamer.SwitchSection(TextSections[i]);
+
if (RelocM == Reloc::DynamicNoPIC) {
const MCSection *sect =
OutContext.getMachOSection("__TEXT", "__symbol_stub4",
@@ -997,7 +1003,7 @@ MCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV) {
void ARMAsmPrinter::
EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
- int Size = TM.getTargetData()->getTypeAllocSize(MCPV->getType());
+ int Size = TM.getDataLayout()->getTypeAllocSize(MCPV->getType());
ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
@@ -1208,16 +1214,6 @@ static void populateADROperands(MCInst &Inst, unsigned Dest,
Inst.addOperand(MCOperand::CreateReg(ccreg));
}
-void ARMAsmPrinter::EmitPatchedInstruction(const MachineInstr *MI,
- unsigned Opcode) {
- MCInst TmpInst;
-
- // Emit the instruction as usual, just patch the opcode.
- LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
- TmpInst.setOpcode(Opcode);
- OutStreamer.EmitInstruction(TmpInst);
-}
-
void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
assert(MI->getFlag(MachineInstr::FrameSetup) &&
"Only instruction which are involved into frame setup code are allowed");
diff --git a/lib/Target/ARM/ARMAsmPrinter.h b/lib/Target/ARM/ARMAsmPrinter.h
index 273f85026d..ee3604499f 100644
--- a/lib/Target/ARM/ARMAsmPrinter.h
+++ b/lib/Target/ARM/ARMAsmPrinter.h
@@ -53,7 +53,7 @@ public:
Subtarget = &TM.getSubtarget<ARMSubtarget>();
}
- virtual const char *getPassName() const {
+ virtual const char *getPassName() const LLVM_OVERRIDE {
return "ARM Assembly Printer";
}
@@ -62,32 +62,31 @@ public:
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
unsigned AsmVariant, const char *ExtraCode,
- raw_ostream &O);
+ raw_ostream &O) LLVM_OVERRIDE;
virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
- unsigned AsmVariant,
- const char *ExtraCode, raw_ostream &O);
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O) LLVM_OVERRIDE;
void EmitJumpTable(const MachineInstr *MI);
void EmitJump2Table(const MachineInstr *MI);
- virtual void EmitInstruction(const MachineInstr *MI);
- bool runOnMachineFunction(MachineFunction &F);
-
- virtual void EmitFunctionBodyEnd();
+ virtual void EmitInstruction(const MachineInstr *MI) LLVM_OVERRIDE;
+ virtual bool runOnMachineFunction(MachineFunction &F) LLVM_OVERRIDE;
// @LOCALMOD-START
// usually this does nothing on ARM as constants pools
// are handled with custom code.
// For the sfi case we do not use the custom logic and fall back
// to the default implementation.
- virtual void EmitConstantPool() {
+ virtual void EmitConstantPool() LLVM_OVERRIDE {
if (FlagSfiDisableCP) AsmPrinter::EmitConstantPool();
}
// @LOCALMOD-END
- virtual void EmitFunctionEntryLabel();
- void EmitStartOfAsmFile(Module &M);
- void EmitEndOfAsmFile(Module &M);
- void EmitXXStructor(const Constant *CV);
+ virtual void EmitFunctionBodyEnd() LLVM_OVERRIDE;
+ virtual void EmitFunctionEntryLabel() LLVM_OVERRIDE;
+ virtual void EmitStartOfAsmFile(Module &M) LLVM_OVERRIDE;
+ virtual void EmitEndOfAsmFile(Module &M) LLVM_OVERRIDE;
+ virtual void EmitXXStructor(const Constant *CV) LLVM_OVERRIDE;
// lowerOperand - Convert a MachineOperand into the equivalent MCOperand.
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp);
@@ -122,12 +121,13 @@ private:
public:
void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
- MachineLocation getDebugValueLocation(const MachineInstr *MI) const;
+ virtual MachineLocation
+ getDebugValueLocation(const MachineInstr *MI) const LLVM_OVERRIDE;
/// EmitDwarfRegOp - Emit dwarf register operation.
- virtual void EmitDwarfRegOp(const MachineLocation &MLoc) const;
+ virtual void EmitDwarfRegOp(const MachineLocation &MLoc) const LLVM_OVERRIDE;
- virtual unsigned getISAEncoding() {
+ virtual unsigned getISAEncoding() LLVM_OVERRIDE {
// ARM/Darwin adds ISA to the DWARF info for each function.
if (!Subtarget->isTargetDarwin())
return 0;
@@ -135,18 +135,19 @@ public:
ARM::DW_ISA_ARM_thumb : ARM::DW_ISA_ARM_arm;
}
+private:
MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol);
- MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
- const MachineBasicBlock *MBB) const;
MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const;
MCSymbol *GetARMSJLJEHLabel(void) const;
MCSymbol *GetARMGVSymbol(const GlobalValue *GV);
+public:
/// EmitMachineConstantPoolValue - Print a machine constantpool value to
/// the .s file.
- virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
+ virtual void
+ EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) LLVM_OVERRIDE;
};
} // end namespace llvm
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 42b6bc3cdc..240c50248e 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -3304,7 +3304,8 @@ ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
// instructions).
if (Latency > 0 && Subtarget.isThumb2()) {
const MachineFunction *MF = DefMI->getParent()->getParent();
- if (MF->getFunction()->getFnAttributes().hasOptimizeForSizeAttr())
+ if (MF->getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize))
--Latency;
}
return Latency;
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index 1cba45c3a5..fa1d0004d7 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -565,8 +565,9 @@ needsStackRealignment(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
const Function *F = MF.getFunction();
unsigned StackAlign = MF.getTarget().getFrameLowering()->getStackAlignment();
- bool requiresRealignment = ((MFI->getMaxAlignment() > StackAlign) ||
- F->getFnAttributes().hasStackAlignmentAttr());
+ bool requiresRealignment =
+ ((MFI->getMaxAlignment() > StackAlign) ||
+ F->getFnAttributes().hasAttribute(Attributes::StackAlignment));
return requiresRealignment && canRealignStack(MF);
}
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index 68406db843..6adbf4f27e 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -47,7 +47,7 @@ namespace {
class ARMCodeEmitter : public MachineFunctionPass {
ARMJITInfo *JTI;
const ARMBaseInstrInfo *II;
- const TargetData *TD;
+ const DataLayout *TD;
const ARMSubtarget *Subtarget;
TargetMachine &TM;
JITCodeEmitter &MCE;
@@ -67,7 +67,7 @@ namespace {
ARMCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce)
: MachineFunctionPass(ID), JTI(0),
II((const ARMBaseInstrInfo *)tm.getInstrInfo()),
- TD(tm.getTargetData()), TM(tm),
+ TD(tm.getDataLayout()), TM(tm),
MCE(mce), MCPEs(0), MJTEs(0),
IsPIC(TM.getRelocationModel() == Reloc::PIC_), IsThumb(false) {}
@@ -376,7 +376,7 @@ bool ARMCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
"JIT relocation model must be set to static or default!");
JTI = ((ARMBaseTargetMachine &)MF.getTarget()).getJITInfo();
II = (const ARMBaseInstrInfo *)MF.getTarget().getInstrInfo();
- TD = MF.getTarget().getTargetData();
+ TD = MF.getTarget().getDataLayout();
Subtarget = &TM.getSubtarget<ARMSubtarget>();
MCPEs = &MF.getConstantPool()->getConstants();
MJTEs = 0;
diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp
index 2c4b9f7cb2..be19a20182 100644
--- a/lib/Target/ARM/ARMConstantIslandPass.cpp
+++ b/lib/Target/ARM/ARMConstantIslandPass.cpp
@@ -22,7 +22,7 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -529,7 +529,7 @@ ARMConstantIslands::doInitialPlacement(std::vector<MachineInstr*> &CPEMIs) {
// identity mapping of CPI's to CPE's.
const std::vector<MachineConstantPoolEntry> &CPs = MCP->getConstants();
- const TargetData &TD = *MF->getTarget().getTargetData();
+ const DataLayout &TD = *MF->getTarget().getDataLayout();
for (unsigned i = 0, e = CPs.size(); i != e; ++i) {
unsigned Size = TD.getTypeAllocSize(CPs[i].getType());
assert(Size >= 4 && "Too small constant pool entry");
diff --git a/lib/Target/ARM/ARMELFWriterInfo.cpp b/lib/Target/ARM/ARMELFWriterInfo.cpp
index f671317d09..d88bf0c8fa 100644
--- a/lib/Target/ARM/ARMELFWriterInfo.cpp
+++ b/lib/Target/ARM/ARMELFWriterInfo.cpp
@@ -15,7 +15,7 @@
#include "ARMRelocations.h"
#include "llvm/Function.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/ELF.h"
@@ -26,8 +26,8 @@ using namespace llvm;
//===----------------------------------------------------------------------===//
ARMELFWriterInfo::ARMELFWriterInfo(TargetMachine &TM)
- : TargetELFWriterInfo(TM.getTargetData()->getPointerSizeInBits() == 64,
- TM.getTargetData()->isLittleEndian()) {
+ : TargetELFWriterInfo(TM.getDataLayout()->getPointerSizeInBits() == 64,
+ TM.getDataLayout()->isLittleEndian()) {
}
ARMELFWriterInfo::~ARMELFWriterInfo() {}
diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp
index 6b49e37e87..8661ab34ea 100644
--- a/lib/Target/ARM/ARMFastISel.cpp
+++ b/lib/Target/ARM/ARMFastISel.cpp
@@ -40,7 +40,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetMachine.h"
@@ -2325,16 +2325,16 @@ bool ARMFastISel::SelectCall(const Instruction *I,
ISD::ArgFlagsTy Flags;
unsigned AttrInd = i - CS.arg_begin() + 1;
- if (CS.paramHasAttr(AttrInd, Attribute::SExt))
+ if (CS.paramHasAttr(AttrInd, Attributes::SExt))
Flags.setSExt();
- if (CS.paramHasAttr(AttrInd, Attribute::ZExt))
+ if (CS.paramHasAttr(AttrInd, Attributes::ZExt))
Flags.setZExt();
// FIXME: Only handle *easy* calls for now.
- if (CS.paramHasAttr(AttrInd, Attribute::InReg) ||
- CS.paramHasAttr(AttrInd, Attribute::StructRet) ||
- CS.paramHasAttr(AttrInd, Attribute::Nest) ||
- CS.paramHasAttr(AttrInd, Attribute::ByVal))
+ if (CS.paramHasAttr(AttrInd, Attributes::InReg) ||
+ CS.paramHasAttr(AttrInd, Attributes::StructRet) ||
+ CS.paramHasAttr(AttrInd, Attributes::Nest) ||
+ CS.paramHasAttr(AttrInd, Attributes::ByVal))
return false;
Type *ArgTy = (*i)->getType();
diff --git a/lib/Target/ARM/ARMFrameLowering.cpp b/lib/Target/ARM/ARMFrameLowering.cpp
index 52374ec4c1..6e991032d0 100644
--- a/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/lib/Target/ARM/ARMFrameLowering.cpp
@@ -1233,7 +1233,7 @@ static void checkNumAlignedDPRCS2Regs(MachineFunction &MF) {
return;
// Naked functions don't spill callee-saved registers.
- if (MF.getFunction()->getFnAttributes().hasNakedAttr())
+ if (MF.getFunction()->getFnAttributes().hasAttribute(Attributes::Naked))
return;
// We are planning to use NEON instructions vst1 / vld1.
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 556dacffcc..474f5bdf06 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -6343,9 +6343,9 @@ EmitSjLjDispatchBlock(MachineInstr *MI, MachineBasicBlock *MBB) const {
const Constant *C = ConstantInt::get(Int32Ty, NumLPads);
// MachineConstantPool wants an explicit alignment.
- unsigned Align = getTargetData()->getPrefTypeAlignment(Int32Ty);
+ unsigned Align = getDataLayout()->getPrefTypeAlignment(Int32Ty);
if (Align == 0)
- Align = getTargetData()->getTypeAllocSize(C->getType());
+ Align = getDataLayout()->getTypeAllocSize(C->getType());
unsigned Idx = ConstantPool->getConstantPoolIndex(C, Align);
unsigned VReg1 = MRI->createVirtualRegister(TRC);
@@ -6432,9 +6432,9 @@ EmitSjLjDispatchBlock(MachineInstr *MI, MachineBasicBlock *MBB) const {
const Constant *C = ConstantInt::get(Int32Ty, NumLPads);
// MachineConstantPool wants an explicit alignment.
- unsigned Align = getTargetData()->getPrefTypeAlignment(Int32Ty);
+ unsigned Align = getDataLayout()->getPrefTypeAlignment(Int32Ty);
if (Align == 0)
- Align = getTargetData()->getTypeAllocSize(C->getType());
+ Align = getDataLayout()->getTypeAllocSize(C->getType());
unsigned Idx = ConstantPool->getConstantPoolIndex(C, Align);
unsigned VReg1 = MRI->createVirtualRegister(TRC);
@@ -6605,7 +6605,8 @@ EmitStructByval(MachineInstr *MI, MachineBasicBlock *BB) const {
UnitSize = 2;
} else {
// Check whether we can use NEON instructions.
- if (!MF->getFunction()->getFnAttributes().hasNoImplicitFloatAttr() &&
+ if (!MF->getFunction()->getFnAttributes().
+ hasAttribute(Attributes::NoImplicitFloat) &&
Subtarget->hasNEON()) {
if ((Align % 16 == 0) && SizeVal >= 16) {
ldrOpc = ARM::VLD1q32wb_fixed;
@@ -6757,9 +6758,9 @@ EmitStructByval(MachineInstr *MI, MachineBasicBlock *BB) const {
const Constant *C = ConstantInt::get(Int32Ty, LoopSize);
// MachineConstantPool wants an explicit alignment.
- unsigned Align = getTargetData()->getPrefTypeAlignment(Int32Ty);
+ unsigned Align = getDataLayout()->getPrefTypeAlignment(Int32Ty);
if (Align == 0)
- Align = getTargetData()->getTypeAllocSize(C->getType());
+ Align = getDataLayout()->getTypeAllocSize(C->getType());
unsigned Idx = ConstantPool->getConstantPoolIndex(C, Align);
AddDefaultPred(BuildMI(BB, dl, TII->get(ARM::LDRcp))
@@ -9343,7 +9344,7 @@ EVT ARMTargetLowering::getOptimalMemOpType(uint64_t Size,
// See if we can use NEON instructions for this...
if (IsZeroVal &&
- !F->getFnAttributes().hasNoImplicitFloatAttr() &&
+ !F->getFnAttributes().hasAttribute(Attributes::NoImplicitFloat) &&
Subtarget->hasNEON()) {
if (memOpAlign(SrcAlign, DstAlign, 16) && Size >= 16) {
return MVT::v4i32;
@@ -10155,7 +10156,7 @@ bool ARMTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
case Intrinsic::arm_neon_vld4lane: {
Info.opc = ISD::INTRINSIC_W_CHAIN;
// Conservatively set memVT to the entire set of vectors loaded.
- uint64_t NumElts = getTargetData()->getTypeAllocSize(I.getType()) / 8;
+ uint64_t NumElts = getDataLayout()->getTypeAllocSize(I.getType()) / 8;
Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
Info.ptrVal = I.getArgOperand(0);
Info.offset = 0;
@@ -10180,7 +10181,7 @@ bool ARMTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
Type *ArgTy = I.getArgOperand(ArgI)->getType();
if (!ArgTy->isVectorTy())
break;
- NumElts += getTargetData()->getTypeAllocSize(ArgTy) / 8;
+ NumElts += getDataLayout()->getTypeAllocSize(ArgTy) / 8;
}
Info.memVT = EVT::getVectorVT(I.getType()->getContext(), MVT::i64, NumElts);
Info.ptrVal = I.getArgOperand(0);
diff --git a/lib/Target/ARM/ARMInstrInfo.cpp b/lib/Target/ARM/ARMInstrInfo.cpp
index e62187727c..a0b6f249a2 100644
--- a/lib/Target/ARM/ARMInstrInfo.cpp
+++ b/lib/Target/ARM/ARMInstrInfo.cpp
@@ -112,7 +112,7 @@ namespace {
"_GLOBAL_OFFSET_TABLE_");
unsigned Id = AFI->createPICLabelUId();
ARMConstantPoolValue *CPV = ARMConstantPoolConstant::Create(GV, Id);
- unsigned Align = TM->getTargetData()->getPrefTypeAlignment(GV->getType());
+ unsigned Align = TM->getDataLayout()->getPrefTypeAlignment(GV->getType());
unsigned Idx = MF.getConstantPool()->getConstantPoolIndex(CPV, Align);
MachineBasicBlock &FirstMBB = MF.front();
diff --git a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
index 0c1b344e0d..a8c8dce0cc 100644
--- a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
+++ b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -27,7 +27,7 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
@@ -1458,7 +1458,7 @@ namespace {
static char ID;
ARMPreAllocLoadStoreOpt() : MachineFunctionPass(ID) {}
- const TargetData *TD;
+ const DataLayout *TD;
const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
const ARMSubtarget *STI;
@@ -1488,7 +1488,7 @@ namespace {
}
bool ARMPreAllocLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
- TD = Fn.getTarget().getTargetData();
+ TD = Fn.getTarget().getDataLayout();
TII = Fn.getTarget().getInstrInfo();
TRI = Fn.getTarget().getRegisterInfo();
STI = &Fn.getTarget().getSubtarget<ARMSubtarget>();
diff --git a/lib/Target/ARM/ARMSelectionDAGInfo.cpp b/lib/Target/ARM/ARMSelectionDAGInfo.cpp
index 59fd484db3..4c44f69f4d 100644
--- a/lib/Target/ARM/ARMSelectionDAGInfo.cpp
+++ b/lib/Target/ARM/ARMSelectionDAGInfo.cpp
@@ -155,7 +155,7 @@ EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
TargetLowering::ArgListEntry Entry;
// First argument: data pointer
- Type *IntPtrTy = TLI.getTargetData()->getIntPtrType(*DAG.getContext());
+ Type *IntPtrTy = TLI.getDataLayout()->getIntPtrType(*DAG.getContext());
Entry.Node = Dst;
Entry.Ty = IntPtrTy;
Args.push_back(Entry);
diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp
index ac5f14c09c..d968dc9f3d 100644
--- a/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/lib/Target/ARM/ARMTargetMachine.cpp
@@ -67,7 +67,7 @@ ARMTargetMachine::ARMTargetMachine(const Target &T, StringRef TT,
CodeGenOpt::Level OL)
: ARMBaseTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
InstrInfo(Subtarget),
- DataLayout(Subtarget.isAPCS_ABI() ?
+ DL(Subtarget.isAPCS_ABI() ?
std::string("e-p:32:32-f64:32:64-i64:32:64-"
"v128:32:128-v64:32:64-n32-S32") :
Subtarget.isAAPCS_ABI() ?
@@ -95,7 +95,7 @@ ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT,
InstrInfo(Subtarget.hasThumb2()
? ((ARMBaseInstrInfo*)new Thumb2InstrInfo(Subtarget))
: ((ARMBaseInstrInfo*)new Thumb1InstrInfo(Subtarget))),
- DataLayout(Subtarget.isAPCS_ABI() ?
+ DL(Subtarget.isAPCS_ABI() ?
std::string("e-p:32:32-f64:32:64-i64:32:64-"
"i16:16:32-i8:8:32-i1:8:32-"
"v128:32:128-v64:32:64-a:0:32-n32-S32") :
diff --git a/lib/Target/ARM/ARMTargetMachine.h b/lib/Target/ARM/ARMTargetMachine.h
index 4da778cd79..076ad01fee 100644
--- a/lib/Target/ARM/ARMTargetMachine.h
+++ b/lib/Target/ARM/ARMTargetMachine.h
@@ -25,7 +25,7 @@
#include "Thumb1FrameLowering.h"
#include "Thumb2InstrInfo.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/ADT/OwningPtr.h"
@@ -69,7 +69,7 @@ public:
class ARMTargetMachine : public ARMBaseTargetMachine {
virtual void anchor();
ARMInstrInfo InstrInfo;
- const TargetData DataLayout; // Calculates type size & alignment
+ const DataLayout DL; // Calculates type size & alignment
ARMELFWriterInfo ELFWriterInfo;
ARMTargetLowering TLInfo;
ARMSelectionDAGInfo TSInfo;
@@ -97,7 +97,7 @@ class ARMTargetMachine : public ARMBaseTargetMachine {
}
virtual const ARMInstrInfo *getInstrInfo() const { return &InstrInfo; }
- virtual const TargetData *getTargetData() const { return &DataLayout; }
+ virtual const DataLayout *getDataLayout() const { return &DL; }
virtual const ARMELFWriterInfo *getELFWriterInfo() const {
return Subtarget.isTargetELF() ? &ELFWriterInfo : 0;
}
@@ -111,7 +111,7 @@ class ThumbTargetMachine : public ARMBaseTargetMachine {
virtual void anchor();
// Either Thumb1InstrInfo or Thumb2InstrInfo.
OwningPtr<ARMBaseInstrInfo> InstrInfo;
- const TargetData DataLayout; // Calculates type size & alignment
+ const DataLayout DL; // Calculates type size & alignment
ARMELFWriterInfo ELFWriterInfo;
ARMTargetLowering TLInfo;
ARMSelectionDAGInfo TSInfo;
@@ -145,7 +145,7 @@ public:
virtual const ARMFrameLowering *getFrameLowering() const {
return FrameLowering.get();
}
- virtual const TargetData *getTargetData() const { return &DataLayout; }
+ virtual const DataLayout *getDataLayout() const { return &DL; }
virtual const ARMELFWriterInfo *getELFWriterInfo() const {
return Subtarget.isTargetELF() ? &ELFWriterInfo : 0;
}
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index aa5ba46ab2..93e5eca625 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -3372,7 +3372,8 @@ ARMAsmParser::OperandMatchResultTy ARMAsmParser::
parseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
SMLoc S = Parser.getTok().getLoc();
const AsmToken &Tok = Parser.getTok();
- assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
+ if (!Tok.is(AsmToken::Identifier))
+ return MatchOperand_NoMatch;
StringRef Mask = Tok.getString();
if (isMClass()) {
@@ -7480,8 +7481,10 @@ MatchAndEmitInstruction(SMLoc IDLoc,
unsigned Kind;
unsigned ErrorInfo;
unsigned MatchResult;
-
- MatchResult = MatchInstructionImpl(Operands, Kind, Inst, ErrorInfo);
+ MatchInstMapAndConstraints MapAndConstraints;
+ MatchResult = MatchInstructionImpl(Operands, Kind, Inst,
+ MapAndConstraints, ErrorInfo,
+ /*matchingInlineAsm*/ false);
switch (MatchResult) {
default: break;
case Match_Success:
diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index dfc424cda2..8abf449206 100644
--- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -620,7 +620,9 @@ public:
const object::mach::CPUSubtypeARM Subtype;
DarwinARMAsmBackend(const Target &T, const StringRef TT,
object::mach::CPUSubtypeARM st)
- : ARMAsmBackend(T, TT), Subtype(st) { }
+ : ARMAsmBackend(T, TT), Subtype(st) {
+ HasDataInCodeSupport = true;
+ }
MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
return createARMMachObjectWriter(OS, /*Is64Bit=*/false,
diff --git a/lib/Target/CMakeLists.txt b/lib/Target/CMakeLists.txt
index 5913a9c4cc..096ef001ed 100644
--- a/lib/Target/CMakeLists.txt
+++ b/lib/Target/CMakeLists.txt
@@ -1,7 +1,6 @@
add_llvm_library(LLVMTarget
Mangler.cpp
Target.cpp
- TargetData.cpp
TargetELFWriterInfo.cpp
TargetInstrInfo.cpp
TargetIntrinsicInfo.cpp
diff --git a/lib/Target/CellSPU/SPUFrameLowering.cpp b/lib/Target/CellSPU/SPUFrameLowering.cpp
index fac806e1b0..f01199515a 100644
--- a/lib/Target/CellSPU/SPUFrameLowering.cpp
+++ b/lib/Target/CellSPU/SPUFrameLowering.cpp
@@ -22,7 +22,7 @@
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/CommandLine.h"
using namespace llvm;
diff --git a/lib/Target/CellSPU/SPUSubtarget.h b/lib/Target/CellSPU/SPUSubtarget.h
index 7c4aa14302..27d28b22dd 100644
--- a/lib/Target/CellSPU/SPUSubtarget.h
+++ b/lib/Target/CellSPU/SPUSubtarget.h
@@ -80,9 +80,9 @@ namespace llvm {
return UseLargeMem;
}
- /// getTargetDataString - Return the pointer size and type alignment
+ /// getDataLayoutString - Return the pointer size and type alignment
/// properties of this subtarget.
- const char *getTargetDataString() const {
+ const char *getDataLayoutString() const {
return "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128"
"-i16:16:128-i8:8:128-i1:8:128-a:0:128-v64:64:128-v128:128:128"
"-s:128:128-n32:64";
diff --git a/lib/Target/CellSPU/SPUTargetMachine.cpp b/lib/Target/CellSPU/SPUTargetMachine.cpp
index 54764f133c..a37ad7f85a 100644
--- a/lib/Target/CellSPU/SPUTargetMachine.cpp
+++ b/lib/Target/CellSPU/SPUTargetMachine.cpp
@@ -38,7 +38,7 @@ SPUTargetMachine::SPUTargetMachine(const Target &T, StringRef TT,
CodeGenOpt::Level OL)
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
Subtarget(TT, CPU, FS),
- DataLayout(Subtarget.getTargetDataString()),
+ DL(Subtarget.getDataLayoutString()),
InstrInfo(*this),
FrameLowering(Subtarget),
TLInfo(*this),
diff --git a/lib/Target/CellSPU/SPUTargetMachine.h b/lib/Target/CellSPU/SPUTargetMachine.h
index 3e5d38c919..58699a30d2 100644
--- a/lib/Target/CellSPU/SPUTargetMachine.h
+++ b/lib/Target/CellSPU/SPUTargetMachine.h
@@ -20,7 +20,7 @@
#include "SPUSelectionDAGInfo.h"
#include "SPUFrameLowering.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
namespace llvm {
@@ -28,7 +28,7 @@ namespace llvm {
///
class SPUTargetMachine : public LLVMTargetMachine {
SPUSubtarget Subtarget;
- const TargetData DataLayout;
+ const DataLayout DL;
SPUInstrInfo InstrInfo;
SPUFrameLowering FrameLowering;
SPUTargetLowering TLInfo;
@@ -70,8 +70,8 @@ public:
return &InstrInfo.getRegisterInfo();
}
- virtual const TargetData *getTargetData() const {
- return &DataLayout;
+ virtual const DataLayout *getDataLayout() const {
+ return &DL;
}
virtual const InstrItineraryData *getInstrItineraryData() const {
diff --git a/lib/Target/CppBackend/CPPTargetMachine.h b/lib/Target/CppBackend/CPPTargetMachine.h
index 9cbe7981a9..30d765d6c9 100644
--- a/lib/Target/CppBackend/CPPTargetMachine.h
+++ b/lib/Target/CppBackend/CPPTargetMachine.h
@@ -15,7 +15,7 @@
#define CPPTARGETMACHINE_H
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
namespace llvm {
@@ -35,7 +35,7 @@ struct CPPTargetMachine : public TargetMachine {
AnalysisID StartAfter,
AnalysisID StopAfter);
- virtual const TargetData *getTargetData() const { return 0; }
+ virtual const DataLayout *getDataLayout() const { return 0; }
};
extern Target TheCppBackendTarget;
diff --git a/lib/Target/Hexagon/HexagonAsmPrinter.cpp b/lib/Target/Hexagon/HexagonAsmPrinter.cpp
index 5fa4740f2a..c15bce608f 100644
--- a/lib/Target/Hexagon/HexagonAsmPrinter.cpp
+++ b/lib/Target/Hexagon/HexagonAsmPrinter.cpp
@@ -46,7 +46,7 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/Mangler.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
diff --git a/lib/Target/Hexagon/HexagonCallingConvLower.cpp b/lib/Target/Hexagon/HexagonCallingConvLower.cpp
index ba8e679ebd..73f9d9acab 100644
--- a/lib/Target/Hexagon/HexagonCallingConvLower.cpp
+++ b/lib/Target/Hexagon/HexagonCallingConvLower.cpp
@@ -16,7 +16,7 @@
#include "HexagonCallingConvLower.h"
#include "Hexagon.h"
#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
diff --git a/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp b/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp
index 2468f0b86f..4d93dd18d4 100644
--- a/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp
+++ b/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp
@@ -50,7 +50,7 @@ bool HexagonRemoveExtendArgs::runOnFunction(Function &F) {
unsigned Idx = 1;
for (Function::arg_iterator AI = F.arg_begin(), AE = F.arg_end(); AI != AE;
++AI, ++Idx) {
- if (F.paramHasAttr(Idx, Attribute::SExt)) {
+ if (F.getParamAttributes(Idx).hasAttribute(Attributes::SExt)) {
Argument* Arg = AI;
if (!isa<PointerType>(Arg->getType())) {
for (Instruction::use_iterator UI = Arg->use_begin();
diff --git a/lib/Target/Hexagon/HexagonTargetMachine.cpp b/lib/Target/Hexagon/HexagonTargetMachine.cpp
index 5688e9cbec..d198a3f45b 100644
--- a/lib/Target/Hexagon/HexagonTargetMachine.cpp
+++ b/lib/Target/Hexagon/HexagonTargetMachine.cpp
@@ -68,7 +68,7 @@ HexagonTargetMachine::HexagonTargetMachine(const Target &T, StringRef TT,
CodeModel::Model CM,
CodeGenOpt::Level OL)
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
- DataLayout("e-p:32:32:32-"
+ DL("e-p:32:32:32-"
"i64:64:64-i32:32:32-i16:16:16-i1:32:32-"
"f64:64:64-f32:32:32-a0:0-n32") ,
Subtarget(TT, CPU, FS), InstrInfo(Subtarget), TLInfo(*this),
diff --git a/lib/Target/Hexagon/HexagonTargetMachine.h b/lib/Target/Hexagon/HexagonTargetMachine.h
index 0336965d11..ade5b3e9c1 100644
--- a/lib/Target/Hexagon/HexagonTargetMachine.h
+++ b/lib/Target/Hexagon/HexagonTargetMachine.h
@@ -20,14 +20,14 @@
#include "HexagonSelectionDAGInfo.h"
#include "HexagonFrameLowering.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
namespace llvm {
class Module;
class HexagonTargetMachine : public LLVMTargetMachine {
- const TargetData DataLayout; // Calculates type size & alignment.
+ const DataLayout DL; // Calculates type size & alignment.
HexagonSubtarget Subtarget;
HexagonInstrInfo InstrInfo;
HexagonTargetLowering TLInfo;
@@ -68,7 +68,7 @@ public:
return &TSInfo;
}
- virtual const TargetData *getTargetData() const { return &DataLayout; }
+ virtual const DataLayout *getDataLayout() const { return &DL; }
static unsigned getModuleMatchQuality(const Module &M);
// Pass Pipeline Configuration.
diff --git a/lib/Target/Hexagon/HexagonTargetObjectFile.cpp b/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
index 32cc709586..f4d7761ac3 100644
--- a/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
+++ b/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
@@ -16,7 +16,7 @@
#include "HexagonTargetMachine.h"
#include "llvm/Function.h"
#include "llvm/GlobalVariable.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/DerivedTypes.h"
#include "llvm/MC/MCContext.h"
#include "llvm/Support/ELF.h"
@@ -73,7 +73,7 @@ IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
if (Kind.isBSS() || Kind.isDataNoRel() || Kind.isCommon()) {
Type *Ty = GV->getType()->getElementType();
- return IsInSmallSection(TM.getTargetData()->getTypeAllocSize(Ty));
+ return IsInSmallSection(TM.getDataLayout()->getTypeAllocSize(Ty));
}
return false;
diff --git a/lib/Target/Hexagon/HexagonVarargsCallingConvention.h b/lib/Target/Hexagon/HexagonVarargsCallingConvention.h
index 9305c2702f..c607b5d356 100644
--- a/lib/Target/Hexagon/HexagonVarargsCallingConvention.h
+++ b/lib/Target/Hexagon/HexagonVarargsCallingConvention.h
@@ -75,9 +75,9 @@ static bool CC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
const Type* ArgTy = LocVT.getTypeForEVT(State.getContext());
unsigned Alignment =
- State.getTarget().getTargetData()->getABITypeAlignment(ArgTy);
+ State.getTarget().getDataLayout()->getABITypeAlignment(ArgTy);
unsigned Size =
- State.getTarget().getTargetData()->getTypeSizeInBits(ArgTy) / 8;
+ State.getTarget().getDataLayout()->getTypeSizeInBits(ArgTy) / 8;
// If it's passed by value, then we need the size of the aggregate not of
// the pointer.
@@ -130,9 +130,9 @@ static bool RetCC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
const Type* ArgTy = LocVT.getTypeForEVT(State.getContext());
unsigned Alignment =
- State.getTarget().getTargetData()->getABITypeAlignment(ArgTy);
+ State.getTarget().getDataLayout()->getABITypeAlignment(ArgTy);
unsigned Size =
- State.getTarget().getTargetData()->getTypeSizeInBits(ArgTy) / 8;
+ State.getTarget().getDataLayout()->getTypeSizeInBits(ArgTy) / 8;
unsigned Offset3 = State.AllocateStack(Size, Alignment);
State.addLoc(CCValAssign::getMem(ValNo, ValVT.getSimpleVT(), Offset3,
diff --git a/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp b/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp
index 9e22fd06d1..d1e18b24c3 100644
--- a/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp
+++ b/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp
@@ -318,8 +318,9 @@ MatchAndEmitInstruction(SMLoc IDLoc,
MCInst Inst;
unsigned Kind;
unsigned ErrorInfo;
-
- switch (MatchInstructionImpl(Operands, Kind, Inst, ErrorInfo)) {
+ MatchInstMapAndConstraints MapAndConstraints;
+ switch (MatchInstructionImpl(Operands, Kind, Inst, MapAndConstraints,
+ ErrorInfo, /*matchingInlineAsm*/ false)) {
default: break;
case Match_Success:
Out.EmitInstruction(Inst);
diff --git a/lib/Target/MBlaze/MBlazeAsmPrinter.cpp b/lib/Target/MBlaze/MBlazeAsmPrinter.cpp
index e9f340f2f6..b679a318c3 100644
--- a/lib/Target/MBlaze/MBlazeAsmPrinter.cpp
+++ b/lib/Target/MBlaze/MBlazeAsmPrinter.cpp
@@ -34,7 +34,7 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
diff --git a/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp b/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp
index e3c7236d11..4ca30ba81f 100644
--- a/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp
+++ b/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp
@@ -16,7 +16,7 @@
#include "llvm/Function.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
@@ -26,8 +26,8 @@ using namespace llvm;
//===----------------------------------------------------------------------===//
MBlazeELFWriterInfo::MBlazeELFWriterInfo(TargetMachine &TM)
- : TargetELFWriterInfo(TM.getTargetData()->getPointerSizeInBits() == 64,
- TM.getTargetData()->isLittleEndian()) {
+ : TargetELFWriterInfo(TM.getDataLayout()->getPointerSizeInBits() == 64,
+ TM.getDataLayout()->isLittleEndian()) {
}
MBlazeELFWriterInfo::~MBlazeELFWriterInfo() {}
diff --git a/lib/Target/MBlaze/MBlazeFrameLowering.cpp b/lib/Target/MBlaze/MBlazeFrameLowering.cpp
index d2f14a5c53..9e467bf337 100644
--- a/lib/Target/MBlaze/MBlazeFrameLowering.cpp
+++ b/lib/Target/MBlaze/MBlazeFrameLowering.cpp
@@ -23,7 +23,7 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
diff --git a/lib/Target/MBlaze/MBlazeTargetMachine.cpp b/lib/Target/MBlaze/MBlazeTargetMachine.cpp
index 5f82f14203..1f2cf6d9d2 100644
--- a/lib/Target/MBlaze/MBlazeTargetMachine.cpp
+++ b/lib/Target/MBlaze/MBlazeTargetMachine.cpp
@@ -38,7 +38,7 @@ MBlazeTargetMachine(const Target &T, StringRef TT,
CodeGenOpt::Level OL)
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
Subtarget(TT, CPU, FS),
- DataLayout("E-p:32:32:32-i8:8:8-i16:16:16"),
+ DL("E-p:32:32:32-i8:8:8-i16:16:16"),
InstrInfo(*this),
FrameLowering(Subtarget),
TLInfo(*this), TSInfo(*this), ELFWriterInfo(*this),
diff --git a/lib/Target/MBlaze/MBlazeTargetMachine.h b/lib/Target/MBlaze/MBlazeTargetMachine.h
index 1647a21692..d949e54f0d 100644
--- a/lib/Target/MBlaze/MBlazeTargetMachine.h
+++ b/lib/Target/MBlaze/MBlazeTargetMachine.h
@@ -23,7 +23,7 @@
#include "MBlazeELFWriterInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetFrameLowering.h"
namespace llvm {
@@ -31,7 +31,7 @@ namespace llvm {
class MBlazeTargetMachine : public LLVMTargetMachine {
MBlazeSubtarget Subtarget;
- const TargetData DataLayout; // Calculates type size & alignment
+ const DataLayout DL; // Calculates type size & alignment
MBlazeInstrInfo InstrInfo;
MBlazeFrameLowering FrameLowering;
MBlazeTargetLowering TLInfo;
@@ -59,8 +59,8 @@ namespace llvm {
virtual const MBlazeSubtarget *getSubtargetImpl() const
{ return &Subtarget; }
- virtual const TargetData *getTargetData() const
- { return &DataLayout;}
+ virtual const DataLayout *getDataLayout() const
+ { return &DL;}
virtual const MBlazeRegisterInfo *getRegisterInfo() const
{ return &InstrInfo.getRegisterInfo(); }
diff --git a/lib/Target/MBlaze/MBlazeTargetObjectFile.cpp b/lib/Target/MBlaze/MBlazeTargetObjectFile.cpp
index f66ea302d9..899c74ee8e 100644
--- a/lib/Target/MBlaze/MBlazeTargetObjectFile.cpp
+++ b/lib/Target/MBlaze/MBlazeTargetObjectFile.cpp
@@ -13,7 +13,7 @@
#include "llvm/GlobalVariable.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSectionELF.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ELF.h"
@@ -70,7 +70,7 @@ IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
return false;
Type *Ty = GV->getType()->getElementType();
- return IsInSmallSection(TM.getTargetData()->getTypeAllocSize(Ty));
+ return IsInSmallSection(TM.getDataLayout()->getTypeAllocSize(Ty));
}
const MCSection *MBlazeTargetObjectFile::
diff --git a/lib/Target/MSP430/MSP430FrameLowering.cpp b/lib/Target/MSP430/MSP430FrameLowering.cpp
index 61d7f2bf47..a312c8d5b2 100644
--- a/lib/Target/MSP430/MSP430FrameLowering.cpp
+++ b/lib/Target/MSP430/MSP430FrameLowering.cpp
@@ -20,7 +20,7 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/CommandLine.h"
diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp
index bda688c31d..fc677aec38 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -61,7 +61,7 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :
TargetLowering(tm, new TargetLoweringObjectFileELF()),
Subtarget(*tm.getSubtargetImpl()) {
- TD = getTargetData();
+ TD = getDataLayout();
// Set up the register classes.
addRegisterClass(MVT::i8, &MSP430::GR8RegClass);
diff --git a/lib/Target/MSP430/MSP430ISelLowering.h b/lib/Target/MSP430/MSP430ISelLowering.h
index d8ad02fca4..991304c23d 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.h
+++ b/lib/Target/MSP430/MSP430ISelLowering.h
@@ -169,7 +169,7 @@ namespace llvm {
SelectionDAG &DAG) const;
const MSP430Subtarget &Subtarget;
- const TargetData *TD;
+ const DataLayout *TD;
};
} // namespace llvm
diff --git a/lib/Target/MSP430/MSP430TargetMachine.cpp b/lib/Target/MSP430/MSP430TargetMachine.cpp
index 817001d6ad..da5899b86d 100644
--- a/lib/Target/MSP430/MSP430TargetMachine.cpp
+++ b/lib/Target/MSP430/MSP430TargetMachine.cpp
@@ -33,8 +33,8 @@ MSP430TargetMachine::MSP430TargetMachine(const Target &T,
CodeGenOpt::Level OL)
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
Subtarget(TT, CPU, FS),
- // FIXME: Check TargetData string.
- DataLayout("e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16"),
+ // FIXME: Check DataLayout string.
+ DL("e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16"),
InstrInfo(*this), TLInfo(*this), TSInfo(*this),
FrameLowering(Subtarget) { }
diff --git a/lib/Target/MSP430/MSP430TargetMachine.h b/lib/Target/MSP430/MSP430TargetMachine.h
index f54146b3e3..ba3cef1f2a 100644
--- a/lib/Target/MSP430/MSP430TargetMachine.h
+++ b/lib/Target/MSP430/MSP430TargetMachine.h
@@ -21,7 +21,7 @@
#include "MSP430SelectionDAGInfo.h"
#include "MSP430RegisterInfo.h"
#include "MSP430Subtarget.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetMachine.h"
@@ -31,7 +31,7 @@ namespace llvm {
///
class MSP430TargetMachine : public LLVMTargetMachine {
MSP430Subtarget Subtarget;
- const TargetData DataLayout; // Calculates type size & alignment
+ const DataLayout DL; // Calculates type size & alignment
MSP430InstrInfo InstrInfo;
MSP430TargetLowering TLInfo;
MSP430SelectionDAGInfo TSInfo;
@@ -47,7 +47,7 @@ public:
return &FrameLowering;
}
virtual const MSP430InstrInfo *getInstrInfo() const { return &InstrInfo; }
- virtual const TargetData *getTargetData() const { return &DataLayout;}
+ virtual const DataLayout *getDataLayout() const { return &DL;}
virtual const MSP430Subtarget *getSubtargetImpl() const { return &Subtarget; }
virtual const TargetRegisterInfo *getRegisterInfo() const {
diff --git a/lib/Target/Mangler.cpp b/lib/Target/Mangler.cpp
index 7fe0d0eb22..539a1f723b 100644
--- a/lib/Target/Mangler.cpp
+++ b/lib/Target/Mangler.cpp
@@ -14,7 +14,7 @@
#include "llvm/Target/Mangler.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/Support/raw_ostream.h"
@@ -157,7 +157,7 @@ void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
/// a suffix on their name indicating the number of words of arguments they
/// take.
static void AddFastCallStdCallSuffix(SmallVectorImpl<char> &OutName,
- const Function *F, const TargetData &TD) {
+ const Function *F, const DataLayout &TD) {
// Calculate arguments size total.
unsigned ArgWords = 0;
for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index b1ada100f4..26fce6a75e 100644
--- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -24,7 +24,31 @@
using namespace llvm;
namespace {
+class MipsAssemblerOptions {
+public:
+ MipsAssemblerOptions():
+ aTReg(1), reorder(true), macro(true) {
+ }
+
+ unsigned getATRegNum() {return aTReg;}
+ bool setATReg(unsigned Reg);
+
+ bool isReorder() {return reorder;}
+ void setReorder() {reorder = true;}
+ void setNoreorder() {reorder = false;}
+
+ bool isMacro() {return macro;}
+ void setMacro() {macro = true;}
+ void setNomacro() {macro = false;}
+
+private:
+ unsigned aTReg;
+ bool reorder;
+ bool macro;
+};
+}
+namespace {
class MipsAsmParser : public MCTargetAsmParser {
enum FpFormatTy {
@@ -37,6 +61,8 @@ class MipsAsmParser : public MCTargetAsmParser {
MCSubtargetInfo &STI;
MCAsmParser &Parser;
+ MipsAssemblerOptions Options;
+
#define GET_ASSEMBLER_HEADER
#include "MipsGenAsmMatcher.inc"
@@ -66,8 +92,26 @@ class MipsAsmParser : public MCTargetAsmParser {
bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
StringRef Mnemonic);
+ bool needsExpansion(MCInst &Inst);
+
+ void expandInstruction(MCInst &Inst, SMLoc IDLoc,
+ SmallVectorImpl<MCInst> &Instructions);
+ void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
+ SmallVectorImpl<MCInst> &Instructions);
+ bool reportParseError(StringRef ErrorMsg);
+
bool parseMemOffset(const MCExpr *&Res);
bool parseRelocOperand(const MCExpr *&Res);
+
+ bool parseDirectiveSet();
+
+ bool parseSetAtDirective();
+ bool parseSetNoAtDirective();
+ bool parseSetMacroDirective();
+ bool parseSetNoMacroDirective();
+ bool parseSetReorderDirective();
+ bool parseSetNoReorderDirective();
+
MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
bool isMips64() const {
@@ -96,6 +140,7 @@ class MipsAsmParser : public MCTargetAsmParser {
unsigned getReg(int RC,int RegNo);
+ unsigned getATReg();
public:
MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
: MCTargetAsmParser(), STI(sti), Parser(parser) {
@@ -256,20 +301,95 @@ public:
};
}
+bool MipsAsmParser::needsExpansion(MCInst &Inst) {
+
+ switch(Inst.getOpcode()) {
+ case Mips::LoadImm32Reg:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
+ SmallVectorImpl<MCInst> &Instructions){
+ switch(Inst.getOpcode()) {
+ case Mips::LoadImm32Reg:
+ return expandLoadImm(Inst, IDLoc, Instructions);
+ }
+}
+
+void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
+ SmallVectorImpl<MCInst> &Instructions){
+ MCInst tmpInst;
+ const MCOperand &ImmOp = Inst.getOperand(1);
+ assert(ImmOp.isImm() && "expected imediate operand kind");
+ const MCOperand &RegOp = Inst.getOperand(0);
+ assert(RegOp.isReg() && "expected register operand kind");
+
+ int ImmValue = ImmOp.getImm();
+ tmpInst.setLoc(IDLoc);
+ if ( 0 <= ImmValue && ImmValue <= 65535) {
+ // for 0 <= j <= 65535.
+ // li d,j => ori d,$zero,j
+ tmpInst.setOpcode(isMips64() ? Mips::ORi64 : Mips::ORi);
+ tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
+ tmpInst.addOperand(
+ MCOperand::CreateReg(isMips64() ? Mips::ZERO_64 : Mips::ZERO));
+ tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
+ Instructions.push_back(tmpInst);
+ } else if ( ImmValue < 0 && ImmValue >= -32768) {
+ // for -32768 <= j < 0.
+ // li d,j => addiu d,$zero,j
+ tmpInst.setOpcode(Mips::ADDiu); //TODO:no ADDiu64 in td files?
+ tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
+ tmpInst.addOperand(
+ MCOperand::CreateReg(isMips64() ? Mips::ZERO_64 : Mips::ZERO));
+ tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
+ Instructions.push_back(tmpInst);
+ } else {
+ // for any other value of j that is representable as a 32-bit integer.
+ // li d,j => lui d,hi16(j)
+ // ori d,d,lo16(j)
+ tmpInst.setOpcode(isMips64() ? Mips::LUi64 : Mips::LUi);
+ tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
+ tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
+ Instructions.push_back(tmpInst);
+ tmpInst.clear();
+ tmpInst.setOpcode(isMips64() ? Mips::ORi64 : Mips::ORi);
+ tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
+ tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
+ tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
+ tmpInst.setLoc(IDLoc);
+ Instructions.push_back(tmpInst);
+ }
+}
+
bool MipsAsmParser::
MatchAndEmitInstruction(SMLoc IDLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCStreamer &Out) {
MCInst Inst;
- unsigned ErrorInfo;
unsigned Kind;
- unsigned MatchResult = MatchInstructionImpl(Operands, Kind, Inst, ErrorInfo);
+ unsigned ErrorInfo;
+ MatchInstMapAndConstraints MapAndConstraints;
+ unsigned MatchResult = MatchInstructionImpl(Operands, Kind, Inst,
+ MapAndConstraints, ErrorInfo,
+ /*matchingInlineAsm*/ false);
switch (MatchResult) {
default: break;
case Match_Success: {
- Inst.setLoc(IDLoc);
- Out.EmitInstruction(Inst);
+ if (needsExpansion(Inst)) {
+ SmallVector<MCInst, 4> Instructions;
+ expandInstruction(Inst, IDLoc, Instructions);
+ for(unsigned i =0; i < Instructions.size(); i++){
+ Out.EmitInstruction(Instructions[i]);
+ }
+ } else {
+ Inst.setLoc(IDLoc);
+ Out.EmitInstruction(Inst);
+ }
return false;
}
case Match_MissingFeature:
@@ -295,54 +415,88 @@ MatchAndEmitInstruction(SMLoc IDLoc,
int MipsAsmParser::matchRegisterName(StringRef Name) {
- int CC = StringSwitch<unsigned>(Name)
- .Case("zero", Mips::ZERO)
- .Case("a0", Mips::A0)
- .Case("a1", Mips::A1)
- .Case("a2", Mips::A2)
- .Case("a3", Mips::A3)
- .Case("v0", Mips::V0)
- .Case("v1", Mips::V1)
- .Case("s0", Mips::S0)
- .Case("s1", Mips::S1)
- .Case("s2", Mips::S2)
- .Case("s3", Mips::S3)
- .Case("s4", Mips::S4)
- .Case("s5", Mips::S5)
- .Case("s6", Mips::S6)
- .Case("s7", Mips::S7)
- .Case("k0", Mips::K0)
- .Case("k1", Mips::K1)
- .Case("sp", Mips::SP)
- .Case("fp", Mips::FP)
- .Case("gp", Mips::GP)
- .Case("ra", Mips::RA)
- .Case("t0", Mips::T0)
- .Case("t1", Mips::T1)
- .Case("t2", Mips::T2)
- .Case("t3", Mips::T3)
- .Case("t4", Mips::T4)
- .Case("t5", Mips::T5)
- .Case("t6", Mips::T6)
- .Case("t7", Mips::T7)
- .Case("t8", Mips::T8)
- .Case("t9", Mips::T9)
- .Case("at", Mips::AT)
- .Case("fcc0", Mips::FCC0)
- .Default(-1);
-
- if (CC != -1) {
- //64 bit register in Mips are following 32 bit definitions.
- if (isMips64())
- CC++;
+ int CC;
+ if (!isMips64())
+ CC = StringSwitch<unsigned>(Name)
+ .Case("zero", Mips::ZERO)
+ .Case("a0", Mips::A0)
+ .Case("a1", Mips::A1)
+ .Case("a2", Mips::A2)
+ .Case("a3", Mips::A3)
+ .Case("v0", Mips::V0)
+ .Case("v1", Mips::V1)
+ .Case("s0", Mips::S0)
+ .Case("s1", Mips::S1)
+ .Case("s2", Mips::S2)
+ .Case("s3", Mips::S3)
+ .Case("s4", Mips::S4)
+ .Case("s5", Mips::S5)
+ .Case("s6", Mips::S6)
+ .Case("s7", Mips::S7)
+ .Case("k0", Mips::K0)
+ .Case("k1", Mips::K1)
+ .Case("sp", Mips::SP)
+ .Case("fp", Mips::FP)
+ .Case("gp", Mips::GP)
+ .Case("ra", Mips::RA)
+ .Case("t0", Mips::T0)
+ .Case("t1", Mips::T1)
+ .Case("t2", Mips::T2)
+ .Case("t3", Mips::T3)
+ .Case("t4", Mips::T4)
+ .Case("t5", Mips::T5)
+ .Case("t6", Mips::T6)
+ .Case("t7", Mips::T7)
+ .Case("t8", Mips::T8)
+ .Case("t9", Mips::T9)
+ .Case("at", Mips::AT)
+ .Case("fcc0", Mips::FCC0)
+ .Default(-1);
+ else
+ CC = StringSwitch<unsigned>(Name)
+ .Case("zero", Mips::ZERO_64)
+ .Case("at", Mips::AT_64)
+ .Case("v0", Mips::V0_64)
+ .Case("v1", Mips::V1_64)
+ .Case("a0", Mips::A0_64)
+ .Case("a1", Mips::A1_64)
+ .Case("a2", Mips::A2_64)
+ .Case("a3", Mips::A3_64)
+ .Case("a4", Mips::T0_64)
+ .Case("a5", Mips::T1_64)
+ .Case("a6", Mips::T2_64)
+ .Case("a7", Mips::T3_64)
+ .Case("t4", Mips::T4_64)
+ .Case("t5", Mips::T5_64)
+ .Case("t6", Mips::T6_64)
+ .Case("t7", Mips::T7_64)
+ .Case("s0", Mips::S0_64)
+ .Case("s1", Mips::S1_64)
+ .Case("s2", Mips::S2_64)
+ .Case("s3", Mips::S3_64)
+ .Case("s4", Mips::S4_64)
+ .Case("s5", Mips::S5_64)
+ .Case("s6", Mips::S6_64)
+ .Case("s7", Mips::S7_64)
+ .Case("t8", Mips::T8_64)
+ .Case("t9", Mips::T9_64)
+ .Case("kt0", Mips::K0_64)
+ .Case("kt1", Mips::K1_64)
+ .Case("gp", Mips::GP_64)
+ .Case("sp", Mips::SP_64)
+ .Case("fp", Mips::FP_64)
+ .Case("s8", Mips::FP_64)
+ .Case("ra", Mips::RA_64)
+ .Default(-1);
+
+ if (CC != -1)
return CC;
- }
if (Name[0] == 'f') {
StringRef NumString = Name.substr(1);
unsigned IntVal;
if( NumString.getAsInteger(10, IntVal))
- return -1; //not integer
+ return -1; // not integer
if (IntVal > 31)
return -1;
@@ -354,7 +508,7 @@ int MipsAsmParser::matchRegisterName(StringRef Name) {
if(isFP64()) {
return getReg(Mips::FGR64RegClassID, IntVal);
}
- //only even numbers available as register pairs
+ // only even numbers available as register pairs
if (( IntVal > 31) || (IntVal%2 != 0))
return -1;
return getReg(Mips::AFGR64RegClassID, IntVal/2);
@@ -392,14 +546,30 @@ void MipsAsmParser::setFpFormat(StringRef Format) {
.Default(FP_FORMAT_NONE);
}
-unsigned MipsAsmParser::getReg(int RC,int RegNo){
+bool MipsAssemblerOptions::setATReg(unsigned Reg) {
+ if (Reg > 31)
+ return false;
+
+ aTReg = Reg;
+ return true;
+}
+
+unsigned MipsAsmParser::getATReg() {
+ unsigned Reg = Options.getATRegNum();
+ if (isMips64())
+ return getReg(Mips::CPU64RegsRegClassID,Reg);
+
+ return getReg(Mips::CPURegsRegClassID,Reg);
+}
+
+unsigned MipsAsmParser::getReg(int RC,int RegNo) {
return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo);
}
-int MipsAsmParser::matchRegisterByNumber(unsigned RegNum,StringRef Mnemonic) {
+int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, StringRef Mnemonic) {
if (Mnemonic.lower() == "rdhwr") {
- //at the moment only hwreg29 is supported
+ // at the moment only hwreg29 is supported
if (RegNum != 29)
return -1;
return Mips::HWR29;
@@ -408,7 +578,8 @@ int MipsAsmParser::matchRegisterByNumber(unsigned RegNum,StringRef Mnemonic) {
if (RegNum > 31)
return -1;
- return getReg(Mips::CPURegsRegClassID,RegNum);
+ // MIPS64 registers are numbered 1 after the 32-bit equivalents
+ return getReg(Mips::CPURegsRegClassID, RegNum) + isMips64();
}
int MipsAsmParser::tryParseRegister(StringRef Mnemonic) {
@@ -419,11 +590,11 @@ int MipsAsmParser::tryParseRegister(StringRef Mnemonic) {
std::string lowerCase = Tok.getString().lower();
RegNum = matchRegisterName(lowerCase);
} else if (Tok.is(AsmToken::Integer))
- RegNum = matchRegisterByNumber(static_cast<unsigned> (Tok.getIntVal()),
+ RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
Mnemonic.lower());
else
return RegNum; //error
- //64 bit div operations require Mips::ZERO instead of MIPS::ZERO_64
+ // 64 bit div operations require Mips::ZERO instead of MIPS::ZERO_64
if (isMips64() && RegNum == Mips::ZERO_64) {
if (Mnemonic.find("ddiv") != StringRef::npos)
RegNum = Mips::ZERO;
@@ -438,11 +609,11 @@ bool MipsAsmParser::
SMLoc S = Parser.getTok().getLoc();
int RegNo = -1;
- //FIXME: we should make a more generic method for CCR
+ // FIXME: we should make a more generic method for CCR
if ((Mnemonic == "cfc1" || Mnemonic == "ctc1")
&& Operands.size() == 2 && Parser.getTok().is(AsmToken::Integer)){
- RegNo = Parser.getTok().getIntVal(); //get the int value
- //at the moment only fcc0 is supported
+ RegNo = Parser.getTok().getIntVal(); // get the int value
+ // at the moment only fcc0 is supported
if (RegNo == 0)
RegNo = Mips::FCC0;
} else
@@ -458,8 +629,8 @@ bool MipsAsmParser::
bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
StringRef Mnemonic) {
- //Check if the current operand has a custom associated parser, if so, try to
- //custom parse the operand, or fallback to the general approach.
+ // Check if the current operand has a custom associated parser, if so, try to
+ // custom parse the operand, or fallback to the general approach.
OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
if (ResTy == MatchOperand_Success)
return false;
@@ -474,20 +645,20 @@ bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
Error(Parser.getTok().getLoc(), "unexpected token in operand");
return true;
case AsmToken::Dollar: {
- //parse register
+ // parse register
SMLoc S = Parser.getTok().getLoc();
Parser.Lex(); // Eat dollar token.
- //parse register operand
- if (!tryParseRegisterOperand(Operands,Mnemonic)) {
+ // parse register operand
+ if (!tryParseRegisterOperand(Operands, Mnemonic)) {
if (getLexer().is(AsmToken::LParen)) {
- //check if it is indexed addressing operand
+ // check if it is indexed addressing operand
Operands.push_back(MipsOperand::CreateToken("(", S));
- Parser.Lex(); //eat parenthesis
+ Parser.Lex(); // eat parenthesis
if (getLexer().isNot(AsmToken::Dollar))
return true;
- Parser.Lex(); //eat dollar
- if (tryParseRegisterOperand(Operands,Mnemonic))
+ Parser.Lex(); // eat dollar
+ if (tryParseRegisterOperand(Operands, Mnemonic))
return true;
if (!getLexer().is(AsmToken::RParen))
@@ -499,7 +670,7 @@ bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
}
return false;
}
- //maybe it is a symbol reference
+ // maybe it is a symbol reference
StringRef Identifier;
if (Parser.ParseIdentifier(Identifier))
return true;
@@ -531,9 +702,9 @@ bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
return false;
}
case AsmToken::Percent: {
- //it is a symbol reference or constant expression
+ // it is a symbol reference or constant expression
const MCExpr *IdVal;
- SMLoc S = Parser.getTok().getLoc(); //start location of the operand
+ SMLoc S = Parser.getTok().getLoc(); // start location of the operand
if (parseRelocOperand(IdVal))
return true;
@@ -541,36 +712,36 @@ bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
return false;
- }//case AsmToken::Percent
- }//switch(getLexer().getKind())
+ } // case AsmToken::Percent
+ } // switch(getLexer().getKind())
return true;
}
bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
- Parser.Lex(); //eat % token
- const AsmToken &Tok = Parser.getTok(); //get next token, operation
+ Parser.Lex(); // eat % token
+ const AsmToken &Tok = Parser.getTok(); // get next token, operation
if (Tok.isNot(AsmToken::Identifier))
return true;
std::string Str = Tok.getIdentifier().str();
- Parser.Lex(); //eat identifier
- //now make expression from the rest of the operand
+ Parser.Lex(); // eat identifier
+ // now make expression from the rest of the operand
const MCExpr *IdVal;
SMLoc EndLoc;
if (getLexer().getKind() == AsmToken::LParen) {
while (1) {
- Parser.Lex(); //eat '(' token
+ Parser.Lex(); // eat '(' token
if (getLexer().getKind() == AsmToken::Percent) {
- Parser.Lex(); //eat % token
+ Parser.Lex(); // eat % token
const AsmToken &nextTok = Parser.getTok();
if (nextTok.isNot(AsmToken::Identifier))
return true;
Str += "(%";
Str += nextTok.getIdentifier();
- Parser.Lex(); //eat identifier
+ Parser.Lex(); // eat identifier
if (getLexer().getKind() != AsmToken::LParen)
return true;
} else
@@ -580,14 +751,14 @@ bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
return true;
while (getLexer().getKind() == AsmToken::RParen)
- Parser.Lex(); //eat ')' token
+ Parser.Lex(); // eat ')' token
} else
- return true; //parenthesis must follow reloc operand
+ return true; // parenthesis must follow reloc operand
- //Check the type of the expression
+ // Check the type of the expression
if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal)) {
- //it's a constant, evaluate lo or hi value
+ // it's a constant, evaluate lo or hi value
int Val = MCE->getValue();
if (Str == "lo") {
Val = Val & 0xffff;
@@ -599,7 +770,7 @@ bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
}
if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(IdVal)) {
- //it's a symbol, create symbolic expression from symbol
+ // it's a symbol, create symbolic expression from symbol
StringRef Symbol = MSRE->getSymbol().getName();
MCSymbolRefExpr::VariantKind VK = getVariantKind(Str);
Res = MCSymbolRefExpr::Create(Symbol,VK,getContext());
@@ -631,7 +802,7 @@ bool MipsAsmParser::parseMemOffset(const MCExpr *&Res) {
case AsmToken::Percent:
return parseRelocOperand(Res);
case AsmToken::LParen:
- return false; //it's probably assuming 0
+ return false; // it's probably assuming 0
}
return true;
}
@@ -641,13 +812,13 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
const MCExpr *IdVal = 0;
SMLoc S;
- //first operand is the offset
+ // first operand is the offset
S = Parser.getTok().getLoc();
if (parseMemOffset(IdVal))
return MatchOperand_ParseFail;
- const AsmToken &Tok = Parser.getTok(); //get next token
+ const AsmToken &Tok = Parser.getTok(); // get next token
if (Tok.isNot(AsmToken::LParen)) {
Error(Parser.getTok().getLoc(), "'(' expected");
return MatchOperand_ParseFail;
@@ -664,11 +835,11 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
}
} else {
- Error(Parser.getTok().getLoc(),"unexpected token in operand");
+ Error(Parser.getTok().getLoc(), "unexpected token in operand");
return MatchOperand_ParseFail;
}
- const AsmToken &Tok2 = Parser.getTok(); //get next token
+ const AsmToken &Tok2 = Parser.getTok(); // get next token
if (Tok2.isNot(AsmToken::RParen)) {
Error(Parser.getTok().getLoc(), "')' expected");
return MatchOperand_ParseFail;
@@ -681,12 +852,12 @@ MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
if (IdVal == 0)
IdVal = MCConstantExpr::Create(0, getContext());
- //now replace register operand with the mem operand
+ // now replace register operand with the mem operand
MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
int RegNo = op->getReg();
- //remove register from operands
+ // remove register from operands
Operands.pop_back();
- //and add memory operand
+ // and add memory operand
Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
delete op;
return MatchOperand_Success;
@@ -743,17 +914,17 @@ static int ConvertCcString(StringRef CondString) {
bool MipsAsmParser::
parseMathOperation(StringRef Name, SMLoc NameLoc,
- SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
- //split the format
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ // split the format
size_t Start = Name.find('.'), Next = Name.rfind('.');
StringRef Format1 = Name.slice(Start, Next);
- //and add the first format to the operands
+ // and add the first format to the operands
Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc));
- //now for the second format
+ // now for the second format
StringRef Format2 = Name.slice(Next, StringRef::npos);
Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc));
- //set the format for the first register
+ // set the format for the first register
setFpFormat(Format1);
// Read the remaining operands.
@@ -797,7 +968,7 @@ parseMathOperation(StringRef Name, SMLoc NameLoc,
bool MipsAsmParser::
ParseInstruction(StringRef Name, SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
- //floating point instructions: should register be treated as double?
+ // floating point instructions: should register be treated as double?
if (requestsDoubleOperand(Name)) {
setFpFormat(FP_FORMAT_D);
Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
@@ -811,8 +982,8 @@ ParseInstruction(StringRef Name, SMLoc NameLoc,
Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc));
if (Next != StringRef::npos) {
- //there is a format token in mnemonic
- //StringRef Rest = Name.slice(Next, StringRef::npos);
+ // there is a format token in mnemonic
+ // StringRef Rest = Name.slice(Next, StringRef::npos);
size_t Dot = Name.find('.', Next+1);
StringRef Format = Name.slice(Next, Dot);
if (Dot == StringRef::npos) //only one '.' in a string, it's a format
@@ -830,11 +1001,11 @@ ParseInstruction(StringRef Name, SMLoc NameLoc,
Operands.push_back(MipsOperand::CreateImm(
MCConstantExpr::Create(Cc, getContext()), NameLoc, E));
} else {
- //trunc, ceil, floor ...
+ // trunc, ceil, floor ...
return parseMathOperation(Name, NameLoc, Operands);
}
- //the rest is a format
+ // the rest is a format
Format = Name.slice(Dot, StringRef::npos);
Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
}
@@ -874,47 +1045,184 @@ ParseInstruction(StringRef Name, SMLoc NameLoc,
return false;
}
-bool MipsAsmParser::
-ParseDirective(AsmToken DirectiveID) {
+bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
+ SMLoc Loc = getLexer().getLoc();
+ Parser.EatToEndOfStatement();
+ return Error(Loc, ErrorMsg);
+}
+
+bool MipsAsmParser::parseSetNoAtDirective() {
+ // line should look like:
+ // .set noat
+ // set at reg to 0
+ Options.setATReg(0);
+ // eat noat
+ Parser.Lex();
+ // if this is not the end of the statement, report error
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ reportParseError("unexpected token in statement");
+ return false;
+ }
+ Parser.Lex(); // Consume the EndOfStatement
+ return false;
+}
+bool MipsAsmParser::parseSetAtDirective() {
+ // line can be
+ // .set at - defaults to $1
+ // or .set at=$reg
+ getParser().Lex();
+ if (getLexer().is(AsmToken::EndOfStatement)) {
+ Options.setATReg(1);
+ Parser.Lex(); // Consume the EndOfStatement
+ return false;
+ } else if (getLexer().is(AsmToken::Equal)) {
+ getParser().Lex(); //eat '='
+ if (getLexer().isNot(AsmToken::Dollar)) {
+ reportParseError("unexpected token in statement");
+ return false;
+ }
+ Parser.Lex(); // eat '$'
+ if (getLexer().isNot(AsmToken::Integer)) {
+ reportParseError("unexpected token in statement");
+ return false;
+ }
+ const AsmToken &Reg = Parser.getTok();
+ if (!Options.setATReg(Reg.getIntVal())) {
+ reportParseError("unexpected token in statement");
+ return false;
+ }
+ getParser().Lex(); //eat reg
+
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ reportParseError("unexpected token in statement");
+ return false;
+ }
+ Parser.Lex(); // Consume the EndOfStatement
+ return false;
+ } else {
+ reportParseError("unexpected token in statement");
+ return false;
+ }
+}
+
+bool MipsAsmParser::parseSetReorderDirective() {
+ Parser.Lex();
+ // if this is not the end of the statement, report error
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ reportParseError("unexpected token in statement");
+ return false;
+ }
+ Options.setReorder();
+ Parser.Lex(); // Consume the EndOfStatement
+ return false;
+}
+
+bool MipsAsmParser::parseSetNoReorderDirective() {
+ Parser.Lex();
+ // if this is not the end of the statement, report error
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ reportParseError("unexpected token in statement");
+ return false;
+ }
+ Options.setNoreorder();
+ Parser.Lex(); // Consume the EndOfStatement
+ return false;
+}
+
+bool MipsAsmParser::parseSetMacroDirective() {
+ Parser.Lex();
+ // if this is not the end of the statement, report error
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ reportParseError("unexpected token in statement");
+ return false;
+ }
+ Options.setMacro();
+ Parser.Lex(); // Consume the EndOfStatement
+ return false;
+}
+
+bool MipsAsmParser::parseSetNoMacroDirective() {
+ Parser.Lex();
+ // if this is not the end of the statement, report error
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ reportParseError("`noreorder' must be set before `nomacro'");
+ return false;
+ }
+ if (Options.isReorder()) {
+ reportParseError("`noreorder' must be set before `nomacro'");
+ return false;
+ }
+ Options.setNomacro();
+ Parser.Lex(); // Consume the EndOfStatement
+ return false;
+}
+bool MipsAsmParser::parseDirectiveSet() {
+
+ // get next token
+ const AsmToken &Tok = Parser.getTok();
+
+ if (Tok.getString() == "noat") {
+ return parseSetNoAtDirective();
+ } else if (Tok.getString() == "at") {
+ return parseSetAtDirective();
+ } else if (Tok.getString() == "reorder") {
+ return parseSetReorderDirective();
+ } else if (Tok.getString() == "noreorder") {
+ return parseSetNoReorderDirective();
+ } else if (Tok.getString() == "macro") {
+ return parseSetMacroDirective();
+ } else if (Tok.getString() == "nomacro") {
+ return parseSetNoMacroDirective();
+ } else if (Tok.getString() == "nomips16") {
+ // ignore this directive for now
+ Parser.EatToEndOfStatement();
+ return false;
+ } else if (Tok.getString() == "nomicromips") {
+ // ignore this directive for now
+ Parser.EatToEndOfStatement();
+ return false;
+ }
+ return true;
+}
+
+bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
if (DirectiveID.getString() == ".ent") {
- //ignore this directive for now
+ // ignore this directive for now
Parser.Lex();
return false;
}
if (DirectiveID.getString() == ".end") {
- //ignore this directive for now
+ // ignore this directive for now
Parser.Lex();
return false;
}
if (DirectiveID.getString() == ".frame") {
- //ignore this directive for now
+ // ignore this directive for now
Parser.EatToEndOfStatement();
return false;
}
if (DirectiveID.getString() == ".set") {
- //ignore this directive for now
- Parser.EatToEndOfStatement();
- return false;
+ return parseDirectiveSet();
}
if (DirectiveID.getString() == ".fmask") {
- //ignore this directive for now
+ // ignore this directive for now
Parser.EatToEndOfStatement();
return false;
}
if (DirectiveID.getString() == ".mask") {
- //ignore this directive for now
+ // ignore this directive for now
Parser.EatToEndOfStatement();
return false;
}
if (DirectiveID.getString() == ".gpword") {
- //ignore this directive for now
+ // ignore this directive for now
Parser.EatToEndOfStatement();
return false;
}
diff --git a/lib/Target/Mips/CMakeLists.txt b/lib/Target/Mips/CMakeLists.txt
index 7dec066fb6..3cc2821d47 100644
--- a/lib/Target/Mips/CMakeLists.txt
+++ b/lib/Target/Mips/CMakeLists.txt
@@ -22,7 +22,6 @@ add_llvm_target(MipsCodeGen
MipsAsmPrinter.cpp
MipsCodeEmitter.cpp
MipsDelaySlotFiller.cpp
- MipsDirectObjLower.cpp
MipsELFWriterInfo.cpp
MipsJITInfo.cpp
MipsInstrInfo.cpp
diff --git a/lib/Target/Mips/MCTargetDesc/CMakeLists.txt b/lib/Target/Mips/MCTargetDesc/CMakeLists.txt
index fa231507a2..be5d7e4253 100644
--- a/lib/Target/Mips/MCTargetDesc/CMakeLists.txt
+++ b/lib/Target/Mips/MCTargetDesc/CMakeLists.txt
@@ -1,5 +1,6 @@
add_llvm_library(LLVMMipsDesc
MipsAsmBackend.cpp
+ MipsDirectObjLower.cpp
MipsMCAsmInfo.cpp
MipsMCCodeEmitter.cpp
MipsMCTargetDesc.cpp
diff --git a/lib/Target/Mips/MipsDirectObjLower.cpp b/lib/Target/Mips/MCTargetDesc/MipsDirectObjLower.cpp
index 0d74db808c..15c4282030 100644
--- a/lib/Target/Mips/MipsDirectObjLower.cpp
+++ b/lib/Target/Mips/MCTargetDesc/MipsDirectObjLower.cpp
@@ -11,8 +11,8 @@
// left to the assembler to lower such as large shifts.
//
//===----------------------------------------------------------------------===//
-#include "MipsDirectObjLower.h"
#include "MipsInstrInfo.h"
+#include "MCTargetDesc/MipsDirectObjLower.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCStreamer.h"
@@ -25,32 +25,28 @@ void Mips::LowerLargeShift(MCInst& Inst) {
assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!");
assert(Inst.getOperand(2).isImm());
- bool isLarge = false;
- int64_t Shift;
- Shift = Inst.getOperand(2).getImm();
- if (Shift > 31) {
- Shift -= 32;
- isLarge = true;
- }
+ int64_t Shift = Inst.getOperand(2).getImm();
+ if (Shift <= 31)
+ return; // Do nothing
+ Shift -= 32;
// saminus32
- (Inst.getOperand(2)).setImm(Shift);
+ Inst.getOperand(2).setImm(Shift);
- if (isLarge)
- switch (Inst.getOpcode()) {
- default:
- // Calling function is not synchronized
- llvm_unreachable("Unexpected shift instruction");
- case Mips::DSLL:
- Inst.setOpcode(Mips::DSLL32);
- return;
- case Mips::DSRL:
- Inst.setOpcode(Mips::DSRL32);
- return;
- case Mips::DSRA:
- Inst.setOpcode(Mips::DSRA32);
- return;
- }
+ switch (Inst.getOpcode()) {
+ default:
+ // Calling function is not synchronized
+ llvm_unreachable("Unexpected shift instruction");
+ case Mips::DSLL:
+ Inst.setOpcode(Mips::DSLL32);
+ return;
+ case Mips::DSRL:
+ Inst.setOpcode(Mips::DSRL32);
+ return;
+ case Mips::DSRA:
+ Inst.setOpcode(Mips::DSRA32);
+ return;
+ }
}
// Pick a DEXT or DINS instruction variant based on the pos and size operands
@@ -70,17 +66,16 @@ void Mips::LowerDextDins(MCInst& InstIn) {
int64_t size = InstIn.getOperand(3).getImm();
if (size <= 32) {
- if ((pos < 32)) { // DEXT/DINS, do nothing
- return;
- } else { // DEXTU/DINSU
- InstIn.getOperand(2).setImm(pos - 32);
- InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU);
+ if (pos < 32) // DEXT/DINS, do nothing
return;
- }
- } else { // DEXTM/DINSM
- assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32");
- InstIn.getOperand(3).setImm(size - 32);
- InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM);
+ // DEXTU/DINSU
+ InstIn.getOperand(2).setImm(pos - 32);
+ InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU);
return;
}
+ // DEXTM/DINSM
+ assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32");
+ InstIn.getOperand(3).setImm(size - 32);
+ InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM);
+ return;
}
diff --git a/lib/Target/Mips/MipsDirectObjLower.h b/lib/Target/Mips/MCTargetDesc/MipsDirectObjLower.h
index 8813cc9ac7..8813cc9ac7 100644
--- a/lib/Target/Mips/MipsDirectObjLower.h
+++ b/lib/Target/Mips/MCTargetDesc/MipsDirectObjLower.h
diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index f3a8d3fb0d..7fbdae02f4 100644
--- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -13,6 +13,7 @@
//
#define DEBUG_TYPE "mccodeemitter"
#include "MCTargetDesc/MipsBaseInfo.h"
+#include "MCTargetDesc/MipsDirectObjLower.h"
#include "MCTargetDesc/MipsFixupKinds.h"
#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "llvm/ADT/APFloat.h"
@@ -109,16 +110,35 @@ void MipsMCCodeEmitter::
EncodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups) const
{
- uint32_t Binary = getBinaryCodeForInstr(MI, Fixups);
+
+ // Non-pseudo instructions that get changed for direct object
+ // only based on operand values.
+ // If this list of instructions get much longer we will move
+ // the check to a function call. Until then, this is more efficient.
+ MCInst TmpInst = MI;
+ switch (MI.getOpcode()) {
+ // If shift amount is >= 32 it the inst needs to be lowered further
+ case Mips::DSLL:
+ case Mips::DSRL:
+ case Mips::DSRA:
+ Mips::LowerLargeShift(TmpInst);
+ break;
+ // Double extract instruction is chosen by pos and size operands
+ case Mips::DEXT:
+ case Mips::DINS:
+ Mips::LowerDextDins(TmpInst);
+ }
+
+ uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups);
// Check for unimplemented opcodes.
- // Unfortunately in MIPS both NOT and SLL will come in with Binary == 0
+ // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0
// so we have to special check for them.
- unsigned Opcode = MI.getOpcode();
+ unsigned Opcode = TmpInst.getOpcode();
if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && !Binary)
llvm_unreachable("unimplemented opcode in EncodeInstruction()");
- const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
+ const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
uint64_t TSFlags = Desc.TSFlags;
// Pseudo instructions don't get encoded and shouldn't be here
@@ -126,8 +146,10 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
if ((TSFlags & MipsII::FormMask) == MipsII::Pseudo)
llvm_unreachable("Pseudo opcode found in EncodeInstruction()");
- // For now all instructions are 4 bytes
- int Size = 4; // FIXME: Have Desc.getSize() return the correct value!
+ // Get byte count of instruction
+ unsigned Size = Desc.getSize();
+ if (!Size)
+ llvm_unreachable("Desc.getSize() returns 0");
EmitInstruction(Binary, Size, OS);
}
diff --git a/lib/Target/Mips/Mips16FrameLowering.cpp b/lib/Target/Mips/Mips16FrameLowering.cpp
index 761581fb2b..056a74efc4 100644
--- a/lib/Target/Mips/Mips16FrameLowering.cpp
+++ b/lib/Target/Mips/Mips16FrameLowering.cpp
@@ -20,7 +20,7 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/CommandLine.h"
diff --git a/lib/Target/Mips/Mips16InstrInfo.td b/lib/Target/Mips/Mips16InstrInfo.td
index b866a5d225..77126bb652 100644
--- a/lib/Target/Mips/Mips16InstrInfo.td
+++ b/lib/Target/Mips/Mips16InstrInfo.td
@@ -10,7 +10,19 @@
// This file describes Mips16 instructions.
//
//===----------------------------------------------------------------------===//
-
+//
+// This are pseudo formats for multiply
+// This first one can be changed to non pseudo now.
+//fmul
+class FMULT16_ins<string asmstr, InstrItinClass itin> :
+ MipsPseudo16<(outs), (ins CPU16Regs:$rx, CPU16Regs:$ry),
+ !strconcat(asmstr, "\t$rx, $ry"), []>;
+
+class FMULT16_LO_ins<string asmstr, InstrItinClass itin> :
+ MipsPseudo16<(outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry),
+ !strconcat(asmstr, "\t$rx, $ry\n\tmflo\t$rz"), []> {
+ let isCodeGenOnly=1;
+}
//
// RRR-type instruction format
//
@@ -43,7 +55,11 @@ class FRR16_ins<bits<5> f, string asmstr, InstrItinClass itin> :
FRR16<f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry),
!strconcat(asmstr, "\t$rx, $ry"), [], itin> {
}
-
+class FRR16_M_ins<bits<5> f, string asmstr,
+ InstrItinClass itin> :
+ FRR16<f, (outs CPU16Regs:$rx), (ins),
+ !strconcat(asmstr, "\t$rx"), [], itin>;
+
class FRxRxRy16_ins<bits<5> f, string asmstr,
InstrItinClass itin> :
FRR16<f, (outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry),
@@ -81,14 +97,13 @@ class FEXT_2RI16_ins<bits<5> _op, string asmstr,
!strconcat(asmstr, "\t$rx, $imm"), [], itin> {
let Constraints = "$rx_ = $rx";
}
+
// this has an explicit sp argument that we ignore to work around a problem
// in the compiler
class FEXT_RI16_SP_explicit_ins<bits<5> _op, string asmstr,
InstrItinClass itin>:
FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins CPUSPReg:$ry, simm16:$imm),
- !strconcat(asmstr, "\t$rx, $imm ( $ry ); "), [], itin> {
-}
-
+ !strconcat(asmstr, "\t$rx, $imm ( $ry ); "), [], itin>;
//
// EXT-RRI instruction format
@@ -245,6 +260,63 @@ def Move32R16: FI8_MOV32R16_ins<"move", IIAlu>;
def MoveR3216: FI8_MOVR3216_ins<"move", IIAlu>;
//
+// Format: MFHI rx MIPS16e
+// Purpose: Move From HI Register
+// To copy the special purpose HI register to a GPR.
+//
+def Mfhi16: FRR16_M_ins<0b10000, "mfhi", IIAlu> {
+ let Uses = [HI];
+ let neverHasSideEffects = 1;
+}
+
+//
+// Format: MFLO rx MIPS16e
+// Purpose: Move From LO Register
+// To copy the special purpose LO register to a GPR.
+//
+def Mflo16: FRR16_M_ins<0b10010, "mflo", IIAlu> {
+ let Uses = [LO];
+ let neverHasSideEffects = 1;
+}
+
+//
+// Pseudo Instruction for mult
+//
+def MultRxRy16: FMULT16_ins<"mult", IIAlu> {
+ let isCommutable = 1;
+ let neverHasSideEffects = 1;
+ let Defs = [HI, LO];
+}
+
+def MultuRxRy16: FMULT16_ins<"multu", IIAlu> {
+ let isCommutable = 1;
+ let neverHasSideEffects = 1;
+ let Defs = [HI, LO];
+}
+
+//
+// Format: MULT rx, ry MIPS16e
+// Purpose: Multiply Word
+// To multiply 32-bit signed integers.
+//
+def MultRxRyRz16: FMULT16_LO_ins<"mult", IIAlu> {
+ let isCommutable = 1;
+ let neverHasSideEffects = 1;
+ let Defs = [HI, LO];
+}
+
+//
+// Format: MULTU rx, ry MIPS16e
+// Purpose: Multiply Unsigned Word
+// To multiply 32-bit unsigned integers.
+//
+def MultuRxRyRz16: FMULT16_LO_ins<"multu", IIAlu> {
+ let isCommutable = 1;
+ let neverHasSideEffects = 1;
+ let Defs = [HI, LO];
+}
+
+//
// Format: NEG rx, ry MIPS16e
// Purpose: Negate
// To negate an integer value.
@@ -413,6 +485,7 @@ class ArithLogic16_pat<SDNode OpNode, Instruction I> :
def: ArithLogic16_pat<add, AdduRxRyRz16>;
def: ArithLogic16_pat<and, AndRxRxRy16>;
+def: ArithLogic16_pat<mul, MultRxRyRz16>;
def: ArithLogic16_pat<or, OrRxRxRy16>;
def: ArithLogic16_pat<sub, SubuRxRyRz16>;
def: ArithLogic16_pat<xor, XorRxRxRy16>;
diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td
index fe1e188303..bd472d6f67 100644
--- a/lib/Target/Mips/Mips64InstrInfo.td
+++ b/lib/Target/Mips/Mips64InstrInfo.td
@@ -83,6 +83,8 @@ let usesCustomInserter = 1, Predicates = [HasMips64, HasStandardEncoding],
//===----------------------------------------------------------------------===//
let DecoderNamespace = "Mips64" in {
/// Arithmetic Instructions (ALU Immediate)
+def DADDi : ArithOverflowI<0x18, "daddi", add, simm16_64, immSExt16,
+ CPU64Regs>;
def DADDiu : ArithLogicI<0x19, "daddiu", add, simm16_64, immSExt16,
CPU64Regs>;
def DANDi : ArithLogicI<0x0c, "andi", and, uimm16_64, immZExt16, CPU64Regs>;
@@ -93,6 +95,7 @@ def XORi64 : ArithLogicI<0x0e, "xori", xor, uimm16_64, immZExt16, CPU64Regs>;
def LUi64 : LoadUpper<0x0f, "lui", CPU64Regs, uimm16_64>;
/// Arithmetic Instructions (3-Operand, R-Type)
+def DADD : ArithOverflowR<0x00, 0x2C, "dadd", IIAlu, CPU64Regs, 1>;
def DADDu : ArithLogicR<0x00, 0x2d, "daddu", add, IIAlu, CPU64Regs, 1>;
def DSUBu : ArithLogicR<0x00, 0x2f, "dsubu", sub, IIAlu, CPU64Regs>;
def SLT64 : SetCC_R<0x00, 0x2a, "slt", setlt, CPU64Regs>;
@@ -307,3 +310,8 @@ def : MipsPat<(i64 (sext_inreg CPU64Regs:$src, i32)),
// bswap MipsPattern
def : MipsPat<(bswap CPU64Regs:$rt), (DSHD (DSBH CPU64Regs:$rt))>;
+
+//===----------------------------------------------------------------------===//
+// Instruction aliases
+//===----------------------------------------------------------------------===//
+def : InstAlias<"move $dst,$src", (DADD CPU64Regs:$dst,CPU64Regs:$src,ZERO_64)>;
diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp
index 1bf4a542d8..b45e7af102 100644
--- a/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -15,7 +15,6 @@
#define DEBUG_TYPE "mips-asm-printer"
#include "Mips.h"
#include "MipsAsmPrinter.h"
-#include "MipsDirectObjLower.h"
#include "MipsInstrInfo.h"
#include "MipsMCInstLower.h"
#include "InstPrinter/MipsInstPrinter.h"
@@ -38,7 +37,7 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/Mangler.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetOptions.h"
@@ -77,22 +76,6 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MCInst TmpInst0;
MCInstLowering.Lower(I++, TmpInst0);
- // Direct object specific instruction lowering
- if (!OutStreamer.hasRawTextSupport()){
- switch (TmpInst0.getOpcode()) {
- // If shift amount is >= 32 it the inst needs to be lowered further
- case Mips::DSLL:
- case Mips::DSRL:
- case Mips::DSRA:
- Mips::LowerLargeShift(TmpInst0);
- break;
- // Double extract instruction is chosen by pos and size operands
- case Mips::DEXT:
- case Mips::DINS:
- Mips::LowerDextDins(TmpInst0);
- }
- }
-
OutStreamer.EmitInstruction(TmpInst0);
} while ((I != E) && I->isInsideBundle()); // Delay slot check
}
diff --git a/lib/Target/Mips/MipsCodeEmitter.cpp b/lib/Target/Mips/MipsCodeEmitter.cpp
index 8e8a2a4c0c..4bfccd8fdd 100644
--- a/lib/Target/Mips/MipsCodeEmitter.cpp
+++ b/lib/Target/Mips/MipsCodeEmitter.cpp
@@ -47,7 +47,7 @@ namespace {
class MipsCodeEmitter : public MachineFunctionPass {
MipsJITInfo *JTI;
const MipsInstrInfo *II;
- const TargetData *TD;
+ const DataLayout *TD;
const MipsSubtarget *Subtarget;
TargetMachine &TM;
JITCodeEmitter &MCE;
@@ -66,7 +66,7 @@ class MipsCodeEmitter : public MachineFunctionPass {
MipsCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce) :
MachineFunctionPass(ID), JTI(0),
II((const MipsInstrInfo *) tm.getInstrInfo()),
- TD(tm.getTargetData()), TM(tm), MCE(mce), MCPEs(0), MJTEs(0),
+ TD(tm.getDataLayout()), TM(tm), MCE(mce), MCPEs(0), MJTEs(0),
IsPIC(TM.getRelocationModel() == Reloc::PIC_) {
}
@@ -128,7 +128,7 @@ char MipsCodeEmitter::ID = 0;
bool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
JTI = ((MipsTargetMachine&) MF.getTarget()).getJITInfo();
II = ((const MipsTargetMachine&) MF.getTarget()).getInstrInfo();
- TD = ((const MipsTargetMachine&) MF.getTarget()).getTargetData();
+ TD = ((const MipsTargetMachine&) MF.getTarget()).getDataLayout();
Subtarget = &TM.getSubtarget<MipsSubtarget> ();
MCPEs = &MF.getConstantPool()->getConstants();
MJTEs = 0;
diff --git a/lib/Target/Mips/MipsELFWriterInfo.cpp b/lib/Target/Mips/MipsELFWriterInfo.cpp
index ac3a54758e..786e6554f0 100644
--- a/lib/Target/Mips/MipsELFWriterInfo.cpp
+++ b/lib/Target/Mips/MipsELFWriterInfo.cpp
@@ -15,7 +15,7 @@
#include "MipsRelocations.h"
#include "llvm/Function.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/ELF.h"
diff --git a/lib/Target/Mips/MipsFrameLowering.cpp b/lib/Target/Mips/MipsFrameLowering.cpp
index 8c0474b0ee..6dd251c054 100644
--- a/lib/Target/Mips/MipsFrameLowering.cpp
+++ b/lib/Target/Mips/MipsFrameLowering.cpp
@@ -23,7 +23,7 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/CommandLine.h"
diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp
index 0d47303e92..f99ff15157 100644
--- a/lib/Target/Mips/MipsISelDAGToDAG.cpp
+++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp
@@ -372,14 +372,16 @@ MipsDAGToDAGISel::SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl, EVT Ty,
SDValue InFlag = SDValue(Mul, 0);
if (HasLo) {
- Lo = CurDAG->getMachineNode(Ty == MVT::i32 ? Mips::MFLO : Mips::MFLO64, dl,
- Ty, MVT::Glue, InFlag);
+ unsigned Opcode = Subtarget.inMips16Mode() ? Mips::Mflo16 :
+ (Ty == MVT::i32 ? Mips::MFLO : Mips::MFLO64);
+ Lo = CurDAG->getMachineNode(Opcode, dl, Ty, MVT::Glue, InFlag);
InFlag = SDValue(Lo, 1);
}
- if (HasHi)
- Hi = CurDAG->getMachineNode(Ty == MVT::i32 ? Mips::MFHI : Mips::MFHI64, dl,
- Ty, InFlag);
-
+ if (HasHi) {
+ unsigned Opcode = Subtarget.inMips16Mode() ? Mips::Mfhi16 :
+ (Ty == MVT::i32 ? Mips::MFHI : Mips::MFHI64);
+ Hi = CurDAG->getMachineNode(Opcode, dl, Ty, InFlag);
+ }
return std::make_pair(Lo, Hi);
}
@@ -443,8 +445,13 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
/// Mul with two results
case ISD::SMUL_LOHI:
case ISD::UMUL_LOHI: {
- if (NodeTy == MVT::i32)
- MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT);
+ if (NodeTy == MVT::i32) {
+ if (Subtarget.inMips16Mode())
+ MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MultuRxRy16 :
+ Mips::MultRxRy16);
+ else
+ MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT);
+ }
else
MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::DMULTu : Mips::DMULT);
@@ -470,8 +477,13 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
}
case ISD::MULHS:
case ISD::MULHU: {
- if (NodeTy == MVT::i32)
- MultOpc = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT);
+ if (NodeTy == MVT::i32) {
+ if (Subtarget.inMips16Mode())
+ MultOpc = (Opcode == ISD::MULHU ?
+ Mips::MultuRxRy16 : Mips::MultRxRy16);
+ else
+ MultOpc = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT);
+ }
else
MultOpc = (Opcode == ISD::MULHU ? Mips::DMULTu : Mips::DMULT);
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index e9f330ffc1..2dd67e065a 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -1758,8 +1758,10 @@ SDValue MipsTargetLowering::LowerBlockAddress(SDValue Op,
if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) {
// %hi/%lo relocation
- SDValue BAHi = DAG.getTargetBlockAddress(BA, MVT::i32, 0, MipsII::MO_ABS_HI);
- SDValue BALo = DAG.getTargetBlockAddress(BA, MVT::i32, 0, MipsII::MO_ABS_LO);
+ SDValue BAHi =
+ DAG.getTargetBlockAddress(BA, MVT::i32, 0, MipsII::MO_ABS_HI);
+ SDValue BALo =
+ DAG.getTargetBlockAddress(BA, MVT::i32, 0, MipsII::MO_ABS_LO);
SDValue Hi = DAG.getNode(MipsISD::Hi, dl, MVT::i32, BAHi);
SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, BALo);
return DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, Lo);
diff --git a/lib/Target/Mips/MipsInstrFormats.td b/lib/Target/Mips/MipsInstrFormats.td
index 8feb853572..1ecbdc2474 100644
--- a/lib/Target/Mips/MipsInstrFormats.td
+++ b/lib/Target/Mips/MipsInstrFormats.td
@@ -92,6 +92,14 @@ class PseudoSE<dag outs, dag ins, string asmstr, list<dag> pattern>:
let Predicates = [HasStandardEncoding];
}
+// Pseudo-instructions for alternate assembly syntax (never used by codegen).
+// These are aliases that require C++ handling to convert to the target
+// instruction, while InstAliases can be handled directly by tblgen.
+class MipsAsmPseudoInst<dag outs, dag ins, string asmstr>:
+ MipsInst<outs, ins, asmstr, [], IIPseudo, Pseudo> {
+ let isPseudo = 1;
+ let Pattern = [];
+}
//===----------------------------------------------------------------------===//
// Format R instruction class in Mips : <|opcode|rs|rt|rd|shamt|funct|>
//===----------------------------------------------------------------------===//
@@ -163,6 +171,27 @@ class FJ<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
let Inst{25-0} = addr;
}
+ //===----------------------------------------------------------------------===//
+// MFC instruction class in Mips : <|op|mf|rt|rd|0000000|sel|>
+//===----------------------------------------------------------------------===//
+class MFC3OP<bits<6> op, bits<5> _mfmt, dag outs, dag ins, string asmstr>:
+ InstSE<outs, ins, asmstr, [], NoItinerary, FrmFR>
+{
+ bits<5> mfmt;
+ bits<5> rt;
+ bits<5> rd;
+ bits<3> sel;
+
+ let Opcode = op;
+ let mfmt = _mfmt;
+
+ let Inst{25-21} = mfmt;
+ let Inst{20-16} = rt;
+ let Inst{15-11} = rd;
+ let Inst{10-3} = 0;
+ let Inst{2-0} = sel;
+}
+
//===----------------------------------------------------------------------===//
//
// FLOATING POINT INSTRUCTION FORMATS
diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td
index 6fa94a96e5..d840ca5152 100644
--- a/lib/Target/Mips/MipsInstrInfo.td
+++ b/lib/Target/Mips/MipsInstrInfo.td
@@ -298,6 +298,23 @@ def addr :
// Instructions specific format
//===----------------------------------------------------------------------===//
+/// Move Control Registers From/To CPU Registers
+def MFC0_3OP : MFC3OP<0x10, 0, (outs CPURegs:$rt),
+ (ins CPURegs:$rd, uimm16:$sel),"mfc0\t$rt, $rd, $sel">;
+def : InstAlias<"mfc0 $rt, $rd", (MFC0_3OP CPURegs:$rt, CPURegs:$rd, 0)>;
+
+def MTC0_3OP : MFC3OP<0x10, 4, (outs CPURegs:$rd, uimm16:$sel),
+ (ins CPURegs:$rt),"mtc0\t$rt, $rd, $sel">;
+def : InstAlias<"mtc0 $rt, $rd", (MTC0_3OP CPURegs:$rd, 0, CPURegs:$rt)>;
+
+def MFC2_3OP : MFC3OP<0x12, 0, (outs CPURegs:$rt),
+ (ins CPURegs:$rd, uimm16:$sel),"mfc2\t$rt, $rd, $sel">;
+def : InstAlias<"mfc2 $rt, $rd", (MFC2_3OP CPURegs:$rt, CPURegs:$rd, 0)>;
+
+def MTC2_3OP : MFC3OP<0x12, 4, (outs CPURegs:$rd, uimm16:$sel),
+ (ins CPURegs:$rt),"mtc2\t$rt, $rd, $sel">;
+def : InstAlias<"mtc2 $rt, $rd", (MTC2_3OP CPURegs:$rd, 0, CPURegs:$rt)>;
+
// Arithmetic and logical instructions with 3 register operands.
class ArithLogicR<bits<6> op, bits<6> func, string instr_asm, SDNode OpNode,
InstrItinClass itin, RegisterClass RC, bit isComm = 0>:
@@ -897,6 +914,10 @@ let usesCustomInserter = 1 in {
// Instruction definition
//===----------------------------------------------------------------------===//
+class LoadImm32< string instr_asm, Operand Od, RegisterClass RC> :
+ MipsAsmPseudoInst<(outs RC:$rt), (ins Od:$imm32),
+ !strconcat(instr_asm, "\t$rt, $imm32")> ;
+def LoadImm32Reg : LoadImm32<"li",shamt,CPURegs>;
//===----------------------------------------------------------------------===//
// MipsI Instructions
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/Mips/MipsSEFrameLowering.cpp b/lib/Target/Mips/MipsSEFrameLowering.cpp
index 1c598471a0..16a6757d66 100644
--- a/lib/Target/Mips/MipsSEFrameLowering.cpp
+++ b/lib/Target/Mips/MipsSEFrameLowering.cpp
@@ -22,7 +22,7 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/CommandLine.h"
diff --git a/lib/Target/Mips/MipsTargetMachine.cpp b/lib/Target/Mips/MipsTargetMachine.cpp
index 515d26534a..199fe5f0d3 100644
--- a/lib/Target/Mips/MipsTargetMachine.cpp
+++ b/lib/Target/Mips/MipsTargetMachine.cpp
@@ -43,7 +43,7 @@ MipsTargetMachine(const Target &T, StringRef TT,
bool isLittle)
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
Subtarget(TT, CPU, FS, isLittle, RM),
- DataLayout(isLittle ?
+ DL(isLittle ?
(Subtarget.isABI_N64() ?
"e-p:64:64:64-i8:8:32-i16:16:32-i64:64:64-f128:128:128-n32" :
"e-p:32:32:32-i8:8:32-i16:16:32-i64:64:64-n32") :
diff --git a/lib/Target/Mips/MipsTargetMachine.h b/lib/Target/Mips/MipsTargetMachine.h
index a542ef6820..3a01828dd1 100644
--- a/lib/Target/Mips/MipsTargetMachine.h
+++ b/lib/Target/Mips/MipsTargetMachine.h
@@ -22,7 +22,7 @@
#include "MipsSubtarget.h"
#include "MipsELFWriterInfo.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetFrameLowering.h"
namespace llvm {
@@ -31,7 +31,7 @@ class MipsRegisterInfo;
class MipsTargetMachine : public LLVMTargetMachine {
MipsSubtarget Subtarget;
- const TargetData DataLayout; // Calculates type size & alignment
+ const DataLayout DL; // Calculates type size & alignment
const MipsInstrInfo *InstrInfo;
const MipsFrameLowering *FrameLowering;
MipsTargetLowering TLInfo;
@@ -54,8 +54,8 @@ public:
{ return FrameLowering; }
virtual const MipsSubtarget *getSubtargetImpl() const
{ return &Subtarget; }
- virtual const TargetData *getTargetData() const
- { return &DataLayout;}
+ virtual const DataLayout *getDataLayout() const
+ { return &DL;}
virtual MipsJITInfo *getJITInfo()
{ return &JITInfo; }
diff --git a/lib/Target/Mips/MipsTargetObjectFile.cpp b/lib/Target/Mips/MipsTargetObjectFile.cpp
index 578dbd03f8..211e6867a7 100644
--- a/lib/Target/Mips/MipsTargetObjectFile.cpp
+++ b/lib/Target/Mips/MipsTargetObjectFile.cpp
@@ -13,7 +13,7 @@
#include "llvm/GlobalVariable.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSectionELF.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ELF.h"
@@ -105,7 +105,7 @@ IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
return false;
Type *Ty = GV->getType()->getElementType();
- return IsInSmallSection(TM.getTargetData()->getTypeAllocSize(Ty));
+ return IsInSmallSection(TM.getDataLayout()->getTypeAllocSize(Ty));
}
diff --git a/lib/Target/NVPTX/NVPTXAllocaHoisting.h b/lib/Target/NVPTX/NVPTXAllocaHoisting.h
index 24b3bd5898..c7cabf6953 100644
--- a/lib/Target/NVPTX/NVPTXAllocaHoisting.h
+++ b/lib/Target/NVPTX/NVPTXAllocaHoisting.h
@@ -16,7 +16,7 @@
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/Pass.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
namespace llvm {
@@ -31,7 +31,7 @@ public:
NVPTXAllocaHoisting() : FunctionPass(ID) {}
void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<TargetData>();
+ AU.addRequired<DataLayout>();
AU.addPreserved<MachineFunctionAnalysis>();
}
diff --git a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
index f2b96163f4..d3dfb35e26 100644
--- a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
+++ b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
@@ -98,10 +98,10 @@ const MCExpr *nvptx::LowerConstant(const Constant *CV, AsmPrinter &AP) {
switch (CE->getOpcode()) {
default:
// If the code isn't optimized, there may be outstanding folding
- // opportunities. Attempt to fold the expression using TargetData as a
+ // opportunities. Attempt to fold the expression using DataLayout as a
// last resort before giving up.
if (Constant *C =
- ConstantFoldConstantExpression(CE, AP.TM.getTargetData()))
+ ConstantFoldConstantExpression(CE, AP.TM.getDataLayout()))
if (C != CE)
return LowerConstant(C, AP);
@@ -115,7 +115,7 @@ const MCExpr *nvptx::LowerConstant(const Constant *CV, AsmPrinter &AP) {
report_fatal_error(OS.str());
}
case Instruction::GetElementPtr: {
- const TargetData &TD = *AP.TM.getTargetData();
+ const DataLayout &TD = *AP.TM.getDataLayout();
// Generate a symbolic expression for the byte address
const Constant *PtrVal = CE->getOperand(0);
SmallVector<Value*, 8> IdxVec(CE->op_begin()+1, CE->op_end());
@@ -145,7 +145,7 @@ const MCExpr *nvptx::LowerConstant(const Constant *CV, AsmPrinter &AP) {
return LowerConstant(CE->getOperand(0), AP);
case Instruction::IntToPtr: {
- const TargetData &TD = *AP.TM.getTargetData();
+ const DataLayout &TD = *AP.TM.getDataLayout();
// Handle casts to pointers by changing them into casts to the appropriate
// integer type. This promotes constant folding and simplifies this code.
Constant *Op = CE->getOperand(0);
@@ -155,7 +155,7 @@ const MCExpr *nvptx::LowerConstant(const Constant *CV, AsmPrinter &AP) {
}
case Instruction::PtrToInt: {
- const TargetData &TD = *AP.TM.getTargetData();
+ const DataLayout &TD = *AP.TM.getDataLayout();
// Support only foldable casts to/from pointers that can be eliminated by
// changing the pointer to the appropriately sized integer type.
Constant *Op = CE->getOperand(0);
@@ -270,7 +270,7 @@ void NVPTXAsmPrinter::EmitInstruction(const MachineInstr *MI) {
void NVPTXAsmPrinter::printReturnValStr(const Function *F,
raw_ostream &O)
{
- const TargetData *TD = TM.getTargetData();
+ const DataLayout *TD = TM.getDataLayout();
const TargetLowering *TLI = TM.getTargetLowering();
Type *Ty = F->getReturnType();
@@ -874,7 +874,7 @@ bool NVPTXAsmPrinter::doInitialization (Module &M) {
const_cast<TargetLoweringObjectFile&>(getObjFileLowering())
.Initialize(OutContext, TM);
- Mang = new Mangler(OutContext, *TM.getTargetData());
+ Mang = new Mangler(OutContext, *TM.getDataLayout());
// Emit header before any dwarf directives are emitted below.
emitHeader(M, OS1);
@@ -1023,7 +1023,7 @@ void NVPTXAsmPrinter::printModuleLevelGV(GlobalVariable* GVar, raw_ostream &O,
return;
}
- const TargetData *TD = TM.getTargetData();
+ const DataLayout *TD = TM.getDataLayout();
// GlobalVariables are always constant pointers themselves.
const PointerType *PTy = GVar->getType();
@@ -1296,7 +1296,7 @@ std::string NVPTXAsmPrinter::getPTXFundamentalTypeStr(const Type *Ty,
void NVPTXAsmPrinter::emitPTXGlobalVariable(const GlobalVariable* GVar,
raw_ostream &O) {
- const TargetData *TD = TM.getTargetData();
+ const DataLayout *TD = TM.getDataLayout();
// GlobalVariables are always constant pointers themselves.
const PointerType *PTy = GVar->getType();
@@ -1342,7 +1342,7 @@ void NVPTXAsmPrinter::emitPTXGlobalVariable(const GlobalVariable* GVar,
static unsigned int
-getOpenCLAlignment(const TargetData *TD,
+getOpenCLAlignment(const DataLayout *TD,
Type *Ty) {
if (Ty->isPrimitiveType() || Ty->isIntegerTy() || isa<PointerType>(Ty))
return TD->getPrefTypeAlignment(Ty);
@@ -1421,7 +1421,7 @@ void NVPTXAsmPrinter::printParamName(int paramIndex, raw_ostream &O) {
void NVPTXAsmPrinter::emitFunctionParamList(const Function *F,
raw_ostream &O) {
- const TargetData *TD = TM.getTargetData();
+ const DataLayout *TD = TM.getDataLayout();
const AttrListPtr &PAL = F->getAttributes();
const TargetLowering *TLI = TM.getTargetLowering();
Function::const_arg_iterator I, E;
@@ -1456,7 +1456,8 @@ void NVPTXAsmPrinter::emitFunctionParamList(const Function *F,
continue;
}
- if (PAL.paramHasAttr(paramIndex+1, Attribute::ByVal) == false) {
+ if (PAL.getParamAttributes(paramIndex+1).
+ hasAttribute(Attributes::ByVal) == false) {
// Just a scalar
const PointerType *PTy = dyn_cast<PointerType>(Ty);
if (isKernelFunc) {
@@ -1714,7 +1715,7 @@ void NVPTXAsmPrinter::printScalarConstant(Constant *CPV, raw_ostream &O) {
void NVPTXAsmPrinter::bufferLEByte(Constant *CPV, int Bytes,
AggBuffer *aggBuffer) {
- const TargetData *TD = TM.getTargetData();
+ const DataLayout *TD = TM.getDataLayout();
if (isa<UndefValue>(CPV) || CPV->isNullValue()) {
int s = TD->getTypeAllocSize(CPV->getType());
@@ -1843,7 +1844,7 @@ void NVPTXAsmPrinter::bufferLEByte(Constant *CPV, int Bytes,
void NVPTXAsmPrinter::bufferAggregateConstant(Constant *CPV,
AggBuffer *aggBuffer) {
- const TargetData *TD = TM.getTargetData();
+ const DataLayout *TD = TM.getDataLayout();
int Bytes;
// Old constants
diff --git a/lib/Target/NVPTX/NVPTXISelLowering.cpp b/lib/Target/NVPTX/NVPTXISelLowering.cpp
index 6ea10ea14a..be771e3567 100644
--- a/lib/Target/NVPTX/NVPTXISelLowering.cpp
+++ b/lib/Target/NVPTX/NVPTXISelLowering.cpp
@@ -402,7 +402,7 @@ std::string NVPTXTargetLowering::getPrototype(Type *retTy,
if (isABI) {
unsigned align = Outs[i].Flags.getByValAlign();
- unsigned sz = getTargetData()->getTypeAllocSize(ETy);
+ unsigned sz = getDataLayout()->getTypeAllocSize(ETy);
O << ".param .align " << align
<< " .b8 ";
O << "_";
@@ -655,11 +655,11 @@ NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
else {
if (Func) { // direct call
if (!llvm::getAlign(*(CS->getCalledFunction()), 0, retAlignment))
- retAlignment = getTargetData()->getABITypeAlignment(retTy);
+ retAlignment = getDataLayout()->getABITypeAlignment(retTy);
} else { // indirect call
const CallInst *CallI = dyn_cast<CallInst>(CS->getInstruction());
if (!llvm::getAlign(*CallI, 0, retAlignment))
- retAlignment = getTargetData()->getABITypeAlignment(retTy);
+ retAlignment = getDataLayout()->getABITypeAlignment(retTy);
}
SDVTList DeclareRetVTs = DAG.getVTList(MVT::Other, MVT::Glue);
SDValue DeclareRetOps[] = { Chain, DAG.getConstant(retAlignment,
@@ -916,7 +916,7 @@ NVPTXTargetLowering::LowerFormalArguments(SDValue Chain,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
- const TargetData *TD = getTargetData();
+ const DataLayout *TD = getDataLayout();
const Function *F = MF.getFunction();
const AttrListPtr &PAL = F->getAttributes();
@@ -965,7 +965,7 @@ NVPTXTargetLowering::LowerFormalArguments(SDValue Chain,
// to newly created nodes. The SDNOdes for params have to
// appear in the same order as their order of appearance
// in the original function. "idx+1" holds that order.
- if (PAL.paramHasAttr(i+1, Attribute::ByVal) == false) {
+ if (PAL.getParamAttributes(i+1).hasAttribute(Attributes::ByVal) == false) {
// A plain scalar.
if (isABI || isKernel) {
// If ABI, load from the param symbol
diff --git a/lib/Target/NVPTX/NVPTXLowerAggrCopies.cpp b/lib/Target/NVPTX/NVPTXLowerAggrCopies.cpp
index 56b237252d..9273931e99 100644
--- a/lib/Target/NVPTX/NVPTXLowerAggrCopies.cpp
+++ b/lib/Target/NVPTX/NVPTXLowerAggrCopies.cpp
@@ -21,7 +21,7 @@
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Support/InstIterator.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
using namespace llvm;
@@ -110,7 +110,7 @@ bool NVPTXLowerAggrCopies::runOnFunction(Function &F) {
SmallVector<MemTransferInst *, 4> aggrMemcpys;
SmallVector<MemSetInst *, 4> aggrMemsets;
- TargetData *TD = &getAnalysis<TargetData>();
+ DataLayout *TD = &getAnalysis<DataLayout>();
LLVMContext &Context = F.getParent()->getContext();
//
diff --git a/lib/Target/NVPTX/NVPTXLowerAggrCopies.h b/lib/Target/NVPTX/NVPTXLowerAggrCopies.h
index ac7f1509f2..b150c69815 100644
--- a/lib/Target/NVPTX/NVPTXLowerAggrCopies.h
+++ b/lib/Target/NVPTX/NVPTXLowerAggrCopies.h
@@ -17,7 +17,7 @@
#include "llvm/Pass.h"
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
namespace llvm {
@@ -28,7 +28,7 @@ struct NVPTXLowerAggrCopies : public FunctionPass {
NVPTXLowerAggrCopies() : FunctionPass(ID) {}
void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<TargetData>();
+ AU.addRequired<DataLayout>();
AU.addPreserved<MachineFunctionAnalysis>();
}
diff --git a/lib/Target/NVPTX/NVPTXTargetMachine.cpp b/lib/Target/NVPTX/NVPTXTargetMachine.cpp
index 433f415a87..dbfc660687 100644
--- a/lib/Target/NVPTX/NVPTXTargetMachine.cpp
+++ b/lib/Target/NVPTX/NVPTXTargetMachine.cpp
@@ -32,7 +32,7 @@
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
@@ -71,7 +71,7 @@ NVPTXTargetMachine::NVPTXTargetMachine(const Target &T,
bool is64bit)
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
Subtarget(TT, CPU, FS, is64bit),
- DataLayout(Subtarget.getDataLayout()),
+ DL(Subtarget.getDataLayout()),
InstrInfo(*this), TLInfo(*this), TSInfo(*this), FrameLowering(*this,is64bit)
/*FrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0)*/ {
}
diff --git a/lib/Target/NVPTX/NVPTXTargetMachine.h b/lib/Target/NVPTX/NVPTXTargetMachine.h
index b3f9cace6b..d58a076858 100644
--- a/lib/Target/NVPTX/NVPTXTargetMachine.h
+++ b/lib/Target/NVPTX/NVPTXTargetMachine.h
@@ -21,7 +21,7 @@
#include "NVPTXSubtarget.h"
#include "NVPTXFrameLowering.h"
#include "ManagedStringPool.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetSelectionDAGInfo.h"
@@ -32,7 +32,7 @@ namespace llvm {
///
class NVPTXTargetMachine : public LLVMTargetMachine {
NVPTXSubtarget Subtarget;
- const TargetData DataLayout; // Calculates type size & alignment
+ const DataLayout DL; // Calculates type size & alignment
NVPTXInstrInfo InstrInfo;
NVPTXTargetLowering TLInfo;
TargetSelectionDAGInfo TSInfo;
@@ -58,7 +58,7 @@ public:
return &FrameLowering;
}
virtual const NVPTXInstrInfo *getInstrInfo() const { return &InstrInfo; }
- virtual const TargetData *getTargetData() const { return &DataLayout;}
+ virtual const DataLayout *getDataLayout() const { return &DL;}
virtual const NVPTXSubtarget *getSubtargetImpl() const { return &Subtarget;}
virtual const NVPTXRegisterInfo *getRegisterInfo() const {
diff --git a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
index 413142eb2b..3d583060d1 100644
--- a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
+++ b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
@@ -136,21 +136,21 @@ void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
- char Value = MI->getOperand(OpNo).getImm();
+ int Value = MI->getOperand(OpNo).getImm();
Value = SignExtend32<5>(Value);
O << (int)Value;
}
void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
- unsigned char Value = MI->getOperand(OpNo).getImm();
+ unsigned int Value = MI->getOperand(OpNo).getImm();
assert(Value <= 31 && "Invalid u5imm argument!");
O << (unsigned int)Value;
}
void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
- unsigned char Value = MI->getOperand(OpNo).getImm();
+ unsigned int Value = MI->getOperand(OpNo).getImm();
assert(Value <= 63 && "Invalid u6imm argument!");
O << (unsigned int)Value;
}
diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
index c0248a6045..1fba5b8dc3 100644
--- a/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
+++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
@@ -168,7 +168,9 @@ unsigned PPCMCCodeEmitter::
get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups) const {
const MCOperand &MO = MI.getOperand(OpNo);
- assert((MI.getOpcode() == PPC::MTCRF || MI.getOpcode() == PPC::MFOCRF) &&
+ assert((MI.getOpcode() == PPC::MTCRF ||
+ MI.getOpcode() == PPC::MFOCRF ||
+ MI.getOpcode() == PPC::MTCRF8) &&
(MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7));
return 0x80 >> getPPCRegisterNumbering(MO.getReg());
}
diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp
index a66677fa0f..914a9b0dce 100644
--- a/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -437,7 +437,7 @@ void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
- const TargetData *TD = TM.getTargetData();
+ const DataLayout *TD = TM.getDataLayout();
bool isPPC64 = TD->getPointerSizeInBits() == 64;
@@ -545,7 +545,7 @@ static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
void PPCDarwinAsmPrinter::
EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
- bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64;
+ bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
const TargetLoweringObjectFileMachO &TLOFMacho =
static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
@@ -640,7 +640,7 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
- bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64;
+ bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
// Darwin/PPC always uses mach-o.
const TargetLoweringObjectFileMachO &TLOFMacho =
diff --git a/lib/Target/PowerPC/PPCFrameLowering.cpp b/lib/Target/PowerPC/PPCFrameLowering.cpp
index d8851a04eb..b1c02e57f8 100644
--- a/lib/Target/PowerPC/PPCFrameLowering.cpp
+++ b/lib/Target/PowerPC/PPCFrameLowering.cpp
@@ -193,7 +193,8 @@ void PPCFrameLowering::determineFrameLayout(MachineFunction &MF) const {
// to adjust the stack pointer (we fit in the Red Zone). For 64-bit
// SVR4, we also require a stack frame if we need to spill the CR,
// since this spill area is addressed relative to the stack pointer.
- bool DisableRedZone = MF.getFunction()->getFnAttributes().hasNoRedZoneAttr();
+ bool DisableRedZone = MF.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::NoRedZone);
// FIXME SVR4 The 32-bit SVR4 ABI has no red zone. However, it can
// still generate stackless code if all local vars are reg-allocated.
// Try: (FrameSize <= 224
@@ -255,7 +256,7 @@ bool PPCFrameLowering::needsFP(const MachineFunction &MF) const {
// Naked functions have no stack frame pushed, so we don't have a frame
// pointer.
- if (MF.getFunction()->getFnAttributes().hasNakedAttr())
+ if (MF.getFunction()->getFnAttributes().hasAttribute(Attributes::Naked))
return false;
return MF.getTarget().Options.DisableFramePointerElim(MF) ||
diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index e8f4d16997..b52452ce89 100644
--- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -701,10 +701,29 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDNode *N) {
}
}
+ SDValue LHS = N->getOperand(0);
+ SDValue RHS = N->getOperand(1);
+
+ // Altivec Vector compare instructions do not set any CR register by default
+ if (LHS.getValueType().isVector()) {
+ unsigned int Opc;
+ if (LHS.getValueType() == MVT::v16i8)
+ Opc = PPC::VCMPEQUB;
+ else if (LHS.getValueType() == MVT::v4i32)
+ Opc = PPC::VCMPEQUW;
+ else if (LHS.getValueType() == MVT::v8i16)
+ Opc = PPC::VCMPEQUH;
+ else if (LHS.getValueType() == MVT::v4f32)
+ Opc = PPC::VCMPEQFP;
+ else
+ llvm_unreachable("Invalid vector compare type: should be expanded by legalize");
+ return CurDAG->SelectNodeTo(N, Opc, LHS.getValueType(), LHS, RHS);
+ }
+
bool Inv;
int OtherCondIdx;
unsigned Idx = getCRIdxForSetCC(CC, Inv, OtherCondIdx);
- SDValue CCReg = SelectCC(N->getOperand(0), N->getOperand(1), CC, dl);
+ SDValue CCReg = SelectCC(LHS, RHS, CC, dl);
SDValue IntCR;
// Force the ccreg into CR7.
@@ -717,7 +736,7 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDNode *N) {
if (PPCSubTarget.hasMFOCRF() && OtherCondIdx == -1)
IntCR = SDValue(CurDAG->getMachineNode(PPC::MFOCRF, dl, MVT::i32, CR7Reg,
CCReg), 0);
- else
+ else
IntCR = SDValue(CurDAG->getMachineNode(PPC::MFCRpseud, dl, MVT::i32,
CR7Reg, CCReg), 0);
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index 27f26cd5fd..64bbcdfa94 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -373,6 +373,10 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
setOperationAction(ISD::LOAD , MVT::v4i32, Legal);
setOperationAction(ISD::SELECT, MVT::v4i32, Expand);
setOperationAction(ISD::STORE , MVT::v4i32, Legal);
+ setOperationAction(ISD::FP_TO_SINT, MVT::v4i32, Legal);
+ setOperationAction(ISD::FP_TO_UINT, MVT::v4i32, Legal);
+ setOperationAction(ISD::SINT_TO_FP, MVT::v4i32, Legal);
+ setOperationAction(ISD::UINT_TO_FP, MVT::v4i32, Legal);
addRegisterClass(MVT::v4f32, &PPC::VRRCRegClass);
addRegisterClass(MVT::v4i32, &PPC::VRRCRegClass);
@@ -538,7 +542,9 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
}
EVT PPCTargetLowering::getSetCCResultType(EVT VT) const {
- return MVT::i32;
+ if (!VT.isVector())
+ return MVT::i32;
+ return VT.changeVectorElementTypeToInteger();
}
//===----------------------------------------------------------------------===//
@@ -1493,7 +1499,7 @@ SDValue PPCTargetLowering::LowerINIT_TRAMPOLINE(SDValue Op,
EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
bool isPPC64 = (PtrVT == MVT::i64);
Type *IntPtrTy =
- DAG.getTargetLoweringInfo().getTargetData()->getIntPtrType(
+ DAG.getTargetLoweringInfo().getDataLayout()->getIntPtrType(
*DAG.getContext());
TargetLowering::ArgListTy Args;
@@ -1716,12 +1722,16 @@ PPCTargetLowering::LowerFormalArguments(SDValue Chain,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals)
const {
- if (PPCSubTarget.isSVR4ABI() && !PPCSubTarget.isPPC64()) {
- return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins,
- dl, DAG, InVals);
+ if (PPCSubTarget.isSVR4ABI()) {
+ if (PPCSubTarget.isPPC64())
+ return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins,
+ dl, DAG, InVals);
+ else
+ return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins,
+ dl, DAG, InVals);
} else {
- return LowerFormalArguments_Darwin_Or_64SVR4(Chain, CallConv, isVarArg, Ins,
- dl, DAG, InVals);
+ return LowerFormalArguments_Darwin(Chain, CallConv, isVarArg, Ins,
+ dl, DAG, InVals);
}
}
@@ -1944,7 +1954,295 @@ PPCTargetLowering::LowerFormalArguments_32SVR4(
}
SDValue
-PPCTargetLowering::LowerFormalArguments_Darwin_Or_64SVR4(
+PPCTargetLowering::LowerFormalArguments_64SVR4(
+ SDValue Chain,
+ CallingConv::ID CallConv, bool isVarArg,
+ const SmallVectorImpl<ISD::InputArg>
+ &Ins,
+ DebugLoc dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
+ // TODO: add description of PPC stack frame format, or at least some docs.
+ //
+ MachineFunction &MF = DAG.getMachineFunction();
+ MachineFrameInfo *MFI = MF.getFrameInfo();
+ PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
+
+ EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
+ // Potential tail calls could cause overwriting of argument stack slots.
+ bool isImmutable = !(getTargetMachine().Options.GuaranteedTailCallOpt &&
+ (CallConv == CallingConv::Fast));
+ unsigned PtrByteSize = 8;
+
+ unsigned ArgOffset = PPCFrameLowering::getLinkageSize(true, true);
+ // Area that is at least reserved in caller of this function.
+ unsigned MinReservedArea = ArgOffset;
+
+ static const uint16_t GPR[] = {
+ PPC::X3, PPC::X4, PPC::X5, PPC::X6,
+ PPC::X7, PPC::X8, PPC::X9, PPC::X10,
+ };
+
+ static const uint16_t *FPR = GetFPR();
+
+ static const uint16_t VR[] = {
+ PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
+ PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
+ };
+
+ const unsigned Num_GPR_Regs = array_lengthof(GPR);
+ const unsigned Num_FPR_Regs = 13;
+ const unsigned Num_VR_Regs = array_lengthof(VR);
+
+ unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
+
+ // Add DAG nodes to load the arguments or copy them out of registers. On
+ // entry to a function on PPC, the arguments start after the linkage area,
+ // although the first ones are often in registers.
+
+ SmallVector<SDValue, 8> MemOps;
+ unsigned nAltivecParamsAtEnd = 0;
+ Function::const_arg_iterator FuncArg = MF.getFunction()->arg_begin();
+ for (unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo, ++FuncArg) {
+ SDValue ArgVal;
+ bool needsLoad = false;
+ EVT ObjectVT = Ins[ArgNo].VT;
+ unsigned ObjSize = ObjectVT.getSizeInBits()/8;
+ unsigned ArgSize = ObjSize;
+ ISD::ArgFlagsTy Flags = Ins[ArgNo].Flags;
+
+ unsigned CurArgOffset = ArgOffset;
+
+ // Varargs or 64 bit Altivec parameters are padded to a 16 byte boundary.
+ if (ObjectVT==MVT::v4f32 || ObjectVT==MVT::v4i32 ||
+ ObjectVT==MVT::v8i16 || ObjectVT==MVT::v16i8) {
+ if (isVarArg) {
+ MinReservedArea = ((MinReservedArea+15)/16)*16;
+ MinReservedArea += CalculateStackSlotSize(ObjectVT,
+ Flags,
+ PtrByteSize);
+ } else
+ nAltivecParamsAtEnd++;
+ } else
+ // Calculate min reserved area.
+ MinReservedArea += CalculateStackSlotSize(Ins[ArgNo].VT,
+ Flags,
+ PtrByteSize);
+
+ // FIXME the codegen can be much improved in some cases.
+ // We do not have to keep everything in memory.
+ if (Flags.isByVal()) {
+ // ObjSize is the true size, ArgSize rounded up to multiple of registers.
+ ObjSize = Flags.getByValSize();
+ ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
+ // All aggregates smaller than 8 bytes must be passed right-justified.
+ if (ObjSize==1 || ObjSize==2) {
+ CurArgOffset = CurArgOffset + (4 - ObjSize);
+ }
+ // The value of the object is its address.
+ int FI = MFI->CreateFixedObject(ObjSize, CurArgOffset, true);
+ SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
+ InVals.push_back(FIN);
+ if (ObjSize==1 || ObjSize==2 || ObjSize==4) {
+ if (GPR_idx != Num_GPR_Regs) {
+ unsigned VReg;
+ VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::G8RCRegClass);
+ SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT);
+ EVT ObjType = (ObjSize == 1 ? MVT::i8 :
+ (ObjSize == 2 ? MVT::i16 : MVT::i32));
+ SDValue Store = DAG.getTruncStore(Val.getValue(1), dl, Val, FIN,
+ MachinePointerInfo(FuncArg,
+ CurArgOffset),
+ ObjType, false, false, 0);
+ MemOps.push_back(Store);
+ ++GPR_idx;
+ }
+
+ ArgOffset += PtrByteSize;
+
+ continue;
+ }
+ for (unsigned j = 0; j < ArgSize; j += PtrByteSize) {
+ // Store whatever pieces of the object are in registers
+ // to memory. ArgOffset will be the address of the beginning
+ // of the object.
+ if (GPR_idx != Num_GPR_Regs) {
+ unsigned VReg;
+ VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::G8RCRegClass);
+ int FI = MFI->CreateFixedObject(PtrByteSize, ArgOffset, true);
+ SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
+ SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT);
+ SDValue Shifted = Val;
+
+ // For 64-bit SVR4, small structs come in right-adjusted.
+ // Shift them left so the following logic works as expected.
+ if (ObjSize < 8) {
+ SDValue ShiftAmt = DAG.getConstant(64 - 8 * ObjSize, PtrVT);
+ Shifted = DAG.getNode(ISD::SHL, dl, PtrVT, Val, ShiftAmt);
+ }
+
+ SDValue Store = DAG.getStore(Val.getValue(1), dl, Shifted, FIN,
+ MachinePointerInfo(FuncArg, ArgOffset),
+ false, false, 0);
+ MemOps.push_back(Store);
+ ++GPR_idx;
+ ArgOffset += PtrByteSize;
+ } else {
+ ArgOffset += ArgSize - (ArgOffset-CurArgOffset);
+ break;
+ }
+ }
+ continue;
+ }
+
+ switch (ObjectVT.getSimpleVT().SimpleTy) {
+ default: llvm_unreachable("Unhandled argument type!");
+ case MVT::i32:
+ case MVT::i64:
+ if (GPR_idx != Num_GPR_Regs) {
+ unsigned VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::G8RCRegClass);
+ ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i64);
+
+ if (ObjectVT == MVT::i32) {
+ // PPC64 passes i8, i16, and i32 values in i64 registers. Promote
+ // value to MVT::i64 and then truncate to the correct register size.
+ if (Flags.isSExt())
+ ArgVal = DAG.getNode(ISD::AssertSext, dl, MVT::i64, ArgVal,
+ DAG.getValueType(ObjectVT));
+ else if (Flags.isZExt())
+ ArgVal = DAG.getNode(ISD::AssertZext, dl, MVT::i64, ArgVal,
+ DAG.getValueType(ObjectVT));
+
+ ArgVal = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, ArgVal);
+ }
+
+ ++GPR_idx;
+ } else {
+ needsLoad = true;
+ ArgSize = PtrByteSize;
+ }
+ ArgOffset += 8;
+ break;
+
+ case MVT::f32:
+ case MVT::f64:
+ // Every 8 bytes of argument space consumes one of the GPRs available for
+ // argument passing.
+ if (GPR_idx != Num_GPR_Regs) {
+ ++GPR_idx;
+ }
+ if (FPR_idx != Num_FPR_Regs) {
+ unsigned VReg;
+
+ if (ObjectVT == MVT::f32)
+ VReg = MF.addLiveIn(FPR[FPR_idx], &PPC::F4RCRegClass);
+ else
+ VReg = MF.addLiveIn(FPR[FPR_idx], &PPC::F8RCRegClass);
+
+ ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, ObjectVT);
+ ++FPR_idx;
+ } else {
+ needsLoad = true;
+ }
+
+ ArgOffset += 8;
+ break;
+ case MVT::v4f32:
+ case MVT::v4i32:
+ case MVT::v8i16:
+ case MVT::v16i8:
+ // Note that vector arguments in registers don't reserve stack space,
+ // except in varargs functions.
+ if (VR_idx != Num_VR_Regs) {
+ unsigned VReg = MF.addLiveIn(VR[VR_idx], &PPC::VRRCRegClass);
+ ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, ObjectVT);
+ if (isVarArg) {
+ while ((ArgOffset % 16) != 0) {
+ ArgOffset += PtrByteSize;
+ if (GPR_idx != Num_GPR_Regs)
+ GPR_idx++;
+ }
+ ArgOffset += 16;
+ GPR_idx = std::min(GPR_idx+4, Num_GPR_Regs); // FIXME correct for ppc64?
+ }
+ ++VR_idx;
+ } else {
+ // Vectors are aligned.
+ ArgOffset = ((ArgOffset+15)/16)*16;
+ CurArgOffset = ArgOffset;
+ ArgOffset += 16;
+ needsLoad = true;
+ }
+ break;
+ }
+
+ // We need to load the argument to a virtual register if we determined
+ // above that we ran out of physical registers of the appropriate type.
+ if (needsLoad) {
+ int FI = MFI->CreateFixedObject(ObjSize,
+ CurArgOffset + (ArgSize - ObjSize),
+ isImmutable);
+ SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
+ ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo(),
+ false, false, false, 0);
+ }
+
+ InVals.push_back(ArgVal);
+ }
+
+ // Set the size that is at least reserved in caller of this function. Tail
+ // call optimized function's reserved stack space needs to be aligned so that
+ // taking the difference between two stack areas will result in an aligned
+ // stack.
+ PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
+ // Add the Altivec parameters at the end, if needed.
+ if (nAltivecParamsAtEnd) {
+ MinReservedArea = ((MinReservedArea+15)/16)*16;
+ MinReservedArea += 16*nAltivecParamsAtEnd;
+ }
+ MinReservedArea =
+ std::max(MinReservedArea,
+ PPCFrameLowering::getMinCallFrameSize(true, true));
+ unsigned TargetAlign
+ = DAG.getMachineFunction().getTarget().getFrameLowering()->
+ getStackAlignment();
+ unsigned AlignMask = TargetAlign-1;
+ MinReservedArea = (MinReservedArea + AlignMask) & ~AlignMask;
+ FI->setMinReservedArea(MinReservedArea);
+
+ // If the function takes variable number of arguments, make a frame index for
+ // the start of the first vararg value... for expansion of llvm.va_start.
+ if (isVarArg) {
+ int Depth = ArgOffset;
+
+ FuncInfo->setVarArgsFrameIndex(
+ MFI->CreateFixedObject(PtrVT.getSizeInBits()/8,
+ Depth, true));
+ SDValue FIN = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
+
+ // If this function is vararg, store any remaining integer argument regs
+ // to their spots on the stack so that they may be loaded by deferencing the
+ // result of va_next.
+ for (; GPR_idx != Num_GPR_Regs; ++GPR_idx) {
+ unsigned VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::G8RCRegClass);
+ SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT);
+ SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN,
+ MachinePointerInfo(), false, false, 0);
+ MemOps.push_back(Store);
+ // Increment the address by four for the next argument to store
+ SDValue PtrOff = DAG.getConstant(PtrVT.getSizeInBits()/8, PtrVT);
+ FIN = DAG.getNode(ISD::ADD, dl, PtrOff.getValueType(), FIN, PtrOff);
+ }
+ }
+
+ if (!MemOps.empty())
+ Chain = DAG.getNode(ISD::TokenFactor, dl,
+ MVT::Other, &MemOps[0], MemOps.size());
+
+ return Chain;
+}
+
+SDValue
+PPCTargetLowering::LowerFormalArguments_Darwin(
SDValue Chain,
CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg>
@@ -1959,7 +2257,6 @@ PPCTargetLowering::LowerFormalArguments_Darwin_Or_64SVR4(
EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
bool isPPC64 = PtrVT == MVT::i64;
- bool isSVR4ABI = PPCSubTarget.isSVR4ABI();
// Potential tail calls could cause overwriting of argument stack slots.
bool isImmutable = !(getTargetMachine().Options.GuaranteedTailCallOpt &&
(CallConv == CallingConv::Fast));
@@ -2080,11 +2377,8 @@ PPCTargetLowering::LowerFormalArguments_Darwin_Or_64SVR4(
// ObjSize is the true size, ArgSize rounded up to multiple of registers.
ObjSize = Flags.getByValSize();
ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
- // FOR DARWIN: Objects of size 1 and 2 are right justified, everything
- // else is left justified. This means the memory address is adjusted
- // forwards.
- // FOR 64-BIT SVR4: All aggregates smaller than 8 bytes must be passed
- // right-justified.
+ // Objects of size 1 and 2 are right justified, everything else is
+ // left justified. This means the memory address is adjusted forwards.
if (ObjSize==1 || ObjSize==2) {
CurArgOffset = CurArgOffset + (4 - ObjSize);
}
@@ -2092,8 +2386,7 @@ PPCTargetLowering::LowerFormalArguments_Darwin_Or_64SVR4(
int FI = MFI->CreateFixedObject(ObjSize, CurArgOffset, true);
SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
InVals.push_back(FIN);
- if (ObjSize==1 || ObjSize==2 ||
- (ObjSize==4 && isSVR4ABI)) {
+ if (ObjSize==1 || ObjSize==2) {
if (GPR_idx != Num_GPR_Regs) {
unsigned VReg;
if (isPPC64)
@@ -2128,16 +2421,7 @@ PPCTargetLowering::LowerFormalArguments_Darwin_Or_64SVR4(
int FI = MFI->CreateFixedObject(PtrByteSize, ArgOffset, true);
SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT);
- SDValue Shifted = Val;
-
- // For 64-bit SVR4, small structs come in right-adjusted.
- // Shift them left so the following logic works as expected.
- if (ObjSize < 8 && isSVR4ABI) {
- SDValue ShiftAmt = DAG.getConstant(64 - 8 * ObjSize, PtrVT);
- Shifted = DAG.getNode(ISD::SHL, dl, PtrVT, Val, ShiftAmt);
- }
-
- SDValue Store = DAG.getStore(Val.getValue(1), dl, Shifted, FIN,
+ SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN,
MachinePointerInfo(FuncArg, ArgOffset),
false, false, 0);
MemOps.push_back(Store);
@@ -6002,7 +6286,8 @@ SDValue PPCTargetLowering::LowerFRAMEADDR(SDValue Op,
bool is31 = (getTargetMachine().Options.DisableFramePointerElim(MF) ||
MFI->hasVarSizedObjects()) &&
MFI->getStackSize() &&
- !MF.getFunction()->getFnAttributes().hasNakedAttr();
+ !MF.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::Naked);
unsigned FrameReg = isPPC64 ? (is31 ? PPC::X31 : PPC::X1) :
(is31 ? PPC::R31 : PPC::R1);
SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg,
diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h
index 40da4cc33c..267c0884d1 100644
--- a/lib/Target/PowerPC/PPCISelLowering.h
+++ b/lib/Target/PowerPC/PPCISelLowering.h
@@ -467,7 +467,13 @@ namespace llvm {
DebugLoc dl, SelectionDAG &DAG) const;
SDValue
- LowerFormalArguments_Darwin_Or_64SVR4(SDValue Chain,
+ LowerFormalArguments_Darwin(SDValue Chain,
+ CallingConv::ID CallConv, bool isVarArg,
+ const SmallVectorImpl<ISD::InputArg> &Ins,
+ DebugLoc dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const;
+ SDValue
+ LowerFormalArguments_64SVR4(SDValue Chain,
CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td
index cfe71d177e..cb0ea01fcf 100644
--- a/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -63,7 +63,7 @@ def HI48_64 : SDNodeXForm<imm, [{
//
let Defs = [LR8] in
- def MovePCtoLR8 : Pseudo<(outs), (ins), "", []>,
+ def MovePCtoLR8 : Pseudo<(outs), (ins), "#MovePCtoLR8", []>,
PPC970_Unit_BRU;
// Darwin ABI Calls.
@@ -141,31 +141,31 @@ def : Pat<(PPCnop),
let usesCustomInserter = 1 in {
let Defs = [CR0] in {
def ATOMIC_LOAD_ADD_I64 : Pseudo<
- (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$incr), "",
+ (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$incr), "#ATOMIC_LOAD_ADD_I64",
[(set G8RC:$dst, (atomic_load_add_64 xoaddr:$ptr, G8RC:$incr))]>;
def ATOMIC_LOAD_SUB_I64 : Pseudo<
- (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$incr), "",
+ (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$incr), "#ATOMIC_LOAD_SUB_I64",
[(set G8RC:$dst, (atomic_load_sub_64 xoaddr:$ptr, G8RC:$incr))]>;
def ATOMIC_LOAD_OR_I64 : Pseudo<
- (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$incr), "",
+ (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$incr), "#ATOMIC_LOAD_OR_I64",
[(set G8RC:$dst, (atomic_load_or_64 xoaddr:$ptr, G8RC:$incr))]>;
def ATOMIC_LOAD_XOR_I64 : Pseudo<
- (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$incr), "",
+ (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$incr), "#ATOMIC_LOAD_XOR_I64",
[(set G8RC:$dst, (atomic_load_xor_64 xoaddr:$ptr, G8RC:$incr))]>;
def ATOMIC_LOAD_AND_I64 : Pseudo<
- (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$incr), "",
+ (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$incr), "#ATOMIC_LOAD_AND_i64",
[(set G8RC:$dst, (atomic_load_and_64 xoaddr:$ptr, G8RC:$incr))]>;
def ATOMIC_LOAD_NAND_I64 : Pseudo<
- (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$incr), "",
+ (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$incr), "#ATOMIC_LOAD_NAND_I64",
[(set G8RC:$dst, (atomic_load_nand_64 xoaddr:$ptr, G8RC:$incr))]>;
def ATOMIC_CMP_SWAP_I64 : Pseudo<
- (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$old, G8RC:$new), "",
+ (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$old, G8RC:$new), "#ATOMIC_CMP_SWAP_I64",
[(set G8RC:$dst,
(atomic_cmp_swap_64 xoaddr:$ptr, G8RC:$old, G8RC:$new))]>;
def ATOMIC_SWAP_I64 : Pseudo<
- (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$new), "",
+ (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$new), "#ATOMIC_SWAP_I64",
[(set G8RC:$dst, (atomic_swap_64 xoaddr:$ptr, G8RC:$new))]>;
}
}
@@ -247,7 +247,7 @@ def MTCRF8 : XFXForm_5<31, 144, (outs crbitm:$FXM), (ins G8RC:$rS),
PPC970_MicroCode, PPC970_Unit_CRU;
def MFCR8pseud: XFXForm_3<31, 19, (outs G8RC:$rT), (ins crbitm:$FXM),
- "", SprMFCR>,
+ "#MFCR8pseud", SprMFCR>,
PPC970_MicroCode, PPC970_Unit_CRU;
def MFCR8 : XFXForm_3<31, 19, (outs G8RC:$rT), (ins),
@@ -278,7 +278,7 @@ def MFTB8 : XFXForm_1_ext<31, 339, 268, (outs G8RC:$rT), (ins),
// the POWER3.
let Defs = [X1], Uses = [X1] in
-def DYNALLOC8 : Pseudo<(outs G8RC:$result), (ins G8RC:$negsize, memri:$fpsi),"",
+def DYNALLOC8 : Pseudo<(outs G8RC:$result), (ins G8RC:$negsize, memri:$fpsi),"#DYNALLOC8",
[(set G8RC:$result,
(PPCdynalloc G8RC:$negsize, iaddr:$fpsi))]>;
@@ -626,15 +626,15 @@ def LD : DSForm_1<58, 0, (outs G8RC:$rD), (ins memrix:$src),
"ld $rD, $src", LdStLD,
[(set G8RC:$rD, (load ixaddr:$src))]>, isPPC64;
def LDtoc: Pseudo<(outs G8RC:$rD), (ins tocentry:$disp, G8RC:$reg),
- "",
+ "#LDtoc",
[(set G8RC:$rD,
(PPCtoc_entry tglobaladdr:$disp, G8RC:$reg))]>, isPPC64;
def LDtocJTI: Pseudo<(outs G8RC:$rD), (ins tocentry:$disp, G8RC:$reg),
- "",
+ "#LDtocJTI",
[(set G8RC:$rD,
(PPCtoc_entry tjumptable:$disp, G8RC:$reg))]>, isPPC64;
def LDtocCPT: Pseudo<(outs G8RC:$rD), (ins tocentry:$disp, G8RC:$reg),
- "",
+ "#LDtocCPT",
[(set G8RC:$rD,
(PPCtoc_entry tconstpool:$disp, G8RC:$reg))]>, isPPC64;
diff --git a/lib/Target/PowerPC/PPCInstrAltivec.td b/lib/Target/PowerPC/PPCInstrAltivec.td
index b0b8423281..ba58c3e4ac 100644
--- a/lib/Target/PowerPC/PPCInstrAltivec.td
+++ b/lib/Target/PowerPC/PPCInstrAltivec.td
@@ -340,6 +340,28 @@ def VCTUXS : VXForm_1<906, (outs VRRC:$vD), (ins u5imm:$UIMM, VRRC:$vB),
"vctuxs $vD, $vB, $UIMM", VecFP,
[(set VRRC:$vD,
(int_ppc_altivec_vctuxs VRRC:$vB, imm:$UIMM))]>;
+
+// Defines with the UIM field set to 0 for floating-point
+// to integer (fp_to_sint/fp_to_uint) conversions and integer
+// to floating-point (sint_to_fp/uint_to_fp) conversions.
+let VA = 0 in {
+def VCFSX_0 : VXForm_1<842, (outs VRRC:$vD), (ins VRRC:$vB),
+ "vcfsx $vD, $vB, 0", VecFP,
+ [(set VRRC:$vD,
+ (int_ppc_altivec_vcfsx VRRC:$vB, 0))]>;
+def VCTUXS_0 : VXForm_1<906, (outs VRRC:$vD), (ins VRRC:$vB),
+ "vctuxs $vD, $vB, 0", VecFP,
+ [(set VRRC:$vD,
+ (int_ppc_altivec_vctuxs VRRC:$vB, 0))]>;
+def VCFUX_0 : VXForm_1<778, (outs VRRC:$vD), (ins VRRC:$vB),
+ "vcfux $vD, $vB, 0", VecFP,
+ [(set VRRC:$vD,
+ (int_ppc_altivec_vcfux VRRC:$vB, 0))]>;
+def VCTSXS_0 : VXForm_1<970, (outs VRRC:$vD), (ins VRRC:$vB),
+ "vctsxs $vD, $vB, 0", VecFP,
+ [(set VRRC:$vD,
+ (int_ppc_altivec_vctsxs VRRC:$vB, 0))]>;
+}
def VEXPTEFP : VX2_Int<394, "vexptefp", int_ppc_altivec_vexptefp>;
def VLOGEFP : VX2_Int<458, "vlogefp", int_ppc_altivec_vlogefp>;
@@ -689,3 +711,13 @@ def : Pat<(v8i16 (sra (v8i16 VRRC:$vA), (v8i16 VRRC:$vB))),
(v8i16 (VSRAH VRRC:$vA, VRRC:$vB))>;
def : Pat<(v4i32 (sra (v4i32 VRRC:$vA), (v4i32 VRRC:$vB))),
(v4i32 (VSRAW VRRC:$vA, VRRC:$vB))>;
+
+// Float to integer and integer to float conversions
+def : Pat<(v4i32 (fp_to_sint (v4f32 VRRC:$vA))),
+ (VCTSXS_0 VRRC:$vA)>;
+def : Pat<(v4i32 (fp_to_uint (v4f32 VRRC:$vA))),
+ (VCTUXS_0 VRRC:$vA)>;
+def : Pat<(v4f32 (sint_to_fp (v4i32 VRRC:$vA))),
+ (VCFSX_0 VRRC:$vA)>;
+def : Pat<(v4f32 (uint_to_fp (v4i32 VRRC:$vA))),
+ (VCFUX_0 VRRC:$vA)>;
diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td
index a503908d8d..3ef3bab957 100644
--- a/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/lib/Target/PowerPC/PPCInstrInfo.td
@@ -369,9 +369,9 @@ def IsBookE : Predicate<"PPCSubTarget.isBookE()">;
let hasCtrlDep = 1 in {
let Defs = [R1], Uses = [R1] in {
-def ADJCALLSTACKDOWN : Pseudo<(outs), (ins u16imm:$amt), "",
+def ADJCALLSTACKDOWN : Pseudo<(outs), (ins u16imm:$amt), "#ADJCALLSTACKDOWN $amt",
[(callseq_start timm:$amt)]>;
-def ADJCALLSTACKUP : Pseudo<(outs), (ins u16imm:$amt1, u16imm:$amt2), "",
+def ADJCALLSTACKUP : Pseudo<(outs), (ins u16imm:$amt1, u16imm:$amt2), "#ADJCALLSTACKUP $amt1 $amt2",
[(callseq_end timm:$amt1, timm:$amt2)]>;
}
@@ -380,7 +380,7 @@ def UPDATE_VRSAVE : Pseudo<(outs GPRC:$rD), (ins GPRC:$rS),
}
let Defs = [R1], Uses = [R1] in
-def DYNALLOC : Pseudo<(outs GPRC:$result), (ins GPRC:$negsize, memri:$fpsi), "",
+def DYNALLOC : Pseudo<(outs GPRC:$result), (ins GPRC:$negsize, memri:$fpsi), "#DYNALLOC",
[(set GPRC:$result,
(PPCdynalloc GPRC:$negsize, iaddr:$fpsi))]>;
@@ -389,19 +389,19 @@ def DYNALLOC : Pseudo<(outs GPRC:$result), (ins GPRC:$negsize, memri:$fpsi), "",
let usesCustomInserter = 1, // Expanded after instruction selection.
PPC970_Single = 1 in {
def SELECT_CC_I4 : Pseudo<(outs GPRC:$dst), (ins CRRC:$cond, GPRC:$T, GPRC:$F,
- i32imm:$BROPC), "",
+ i32imm:$BROPC), "#SELECT_CC_I4",
[]>;
def SELECT_CC_I8 : Pseudo<(outs G8RC:$dst), (ins CRRC:$cond, G8RC:$T, G8RC:$F,
- i32imm:$BROPC), "",
+ i32imm:$BROPC), "#SELECT_CC_I8",
[]>;
def SELECT_CC_F4 : Pseudo<(outs F4RC:$dst), (ins CRRC:$cond, F4RC:$T, F4RC:$F,
- i32imm:$BROPC), "",
+ i32imm:$BROPC), "#SELECT_CC_F4",
[]>;
def SELECT_CC_F8 : Pseudo<(outs F8RC:$dst), (ins CRRC:$cond, F8RC:$T, F8RC:$F,
- i32imm:$BROPC), "",
+ i32imm:$BROPC), "#SELECT_CC_F8",
[]>;
def SELECT_CC_VRRC: Pseudo<(outs VRRC:$dst), (ins CRRC:$cond, VRRC:$T, VRRC:$F,
- i32imm:$BROPC), "",
+ i32imm:$BROPC), "#SELECT_CC_VRRC",
[]>;
}
@@ -409,16 +409,16 @@ let usesCustomInserter = 1, // Expanded after instruction selection.
// scavenge a register for it.
let mayStore = 1 in
def SPILL_CR : Pseudo<(outs), (ins CRRC:$cond, memri:$F),
- "", []>;
+ "#SPILL_CR", []>;
// RESTORE_CR - Indicate that we're restoring the CR register (previously
// spilled), so we'll need to scavenge a register for it.
let mayLoad = 1 in
def RESTORE_CR : Pseudo<(outs CRRC:$cond), (ins memri:$F),
- "", []>;
+ "#RESTORE_CR", []>;
let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7 in {
- let isReturn = 1, Uses = [LR, RM] in
+ let isCodeGenOnly = 1, isReturn = 1, Uses = [LR, RM] in
def BLR : XLForm_2_br<19, 16, 0, (outs), (ins pred:$p),
"b${p:cc}lr ${p:reg}", BrB,
[(retflag)]>;
@@ -427,7 +427,7 @@ let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7 in {
}
let Defs = [LR] in
- def MovePCtoLR : Pseudo<(outs), (ins), "", []>,
+ def MovePCtoLR : Pseudo<(outs), (ins), "#MovePCtoLR", []>,
PPC970_Unit_BRU;
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7 in {
@@ -439,10 +439,11 @@ let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7 in {
// BCC represents an arbitrary conditional branch on a predicate.
// FIXME: should be able to write a pattern for PPCcondbranch, but can't use
- // a two-value operand where a dag node expects two operands. :(
- def BCC : BForm<16, 0, 0, (outs), (ins pred:$cond, condbrtarget:$dst),
- "b${cond:cc} ${cond:reg}, $dst"
- /*[(PPCcondbranch CRRC:$crS, imm:$opc, bb:$dst)]*/>;
+ // a two-value operand where a dag node expects two operands. :(
+ let isCodeGenOnly = 1 in
+ def BCC : BForm<16, 0, 0, (outs), (ins pred:$cond, condbrtarget:$dst),
+ "b${cond:cc} ${cond:reg}, $dst"
+ /*[(PPCcondbranch CRRC:$crS, imm:$opc, bb:$dst)]*/>;
let Defs = [CTR], Uses = [CTR] in {
def BDZ : IForm_ext<16, 18, 0, 0, (outs), (ins condbrtarget:$dst),
@@ -564,81 +565,81 @@ def : Pat<(prefetch xoaddr:$dst, (i32 0), imm, (i32 1)),
let usesCustomInserter = 1 in {
let Defs = [CR0] in {
def ATOMIC_LOAD_ADD_I8 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "#ATOMIC_LOAD_ADD_I8",
[(set GPRC:$dst, (atomic_load_add_8 xoaddr:$ptr, GPRC:$incr))]>;
def ATOMIC_LOAD_SUB_I8 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "#ATOMIC_LOAD_SUB_I8",
[(set GPRC:$dst, (atomic_load_sub_8 xoaddr:$ptr, GPRC:$incr))]>;
def ATOMIC_LOAD_AND_I8 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "#ATOMIC_LOAD_AND_I8",
[(set GPRC:$dst, (atomic_load_and_8 xoaddr:$ptr, GPRC:$incr))]>;
def ATOMIC_LOAD_OR_I8 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "#ATOMIC_LOAD_OR_I8",
[(set GPRC:$dst, (atomic_load_or_8 xoaddr:$ptr, GPRC:$incr))]>;
def ATOMIC_LOAD_XOR_I8 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "ATOMIC_LOAD_XOR_I8",
[(set GPRC:$dst, (atomic_load_xor_8 xoaddr:$ptr, GPRC:$incr))]>;
def ATOMIC_LOAD_NAND_I8 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "#ATOMIC_LOAD_NAND_I8",
[(set GPRC:$dst, (atomic_load_nand_8 xoaddr:$ptr, GPRC:$incr))]>;
def ATOMIC_LOAD_ADD_I16 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "#ATOMIC_LOAD_ADD_I16",
[(set GPRC:$dst, (atomic_load_add_16 xoaddr:$ptr, GPRC:$incr))]>;
def ATOMIC_LOAD_SUB_I16 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "#ATOMIC_LOAD_SUB_I16",
[(set GPRC:$dst, (atomic_load_sub_16 xoaddr:$ptr, GPRC:$incr))]>;
def ATOMIC_LOAD_AND_I16 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "#ATOMIC_LOAD_AND_I16",
[(set GPRC:$dst, (atomic_load_and_16 xoaddr:$ptr, GPRC:$incr))]>;
def ATOMIC_LOAD_OR_I16 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "#ATOMIC_LOAD_OR_I16",
[(set GPRC:$dst, (atomic_load_or_16 xoaddr:$ptr, GPRC:$incr))]>;
def ATOMIC_LOAD_XOR_I16 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "#ATOMIC_LOAD_XOR_I16",
[(set GPRC:$dst, (atomic_load_xor_16 xoaddr:$ptr, GPRC:$incr))]>;
def ATOMIC_LOAD_NAND_I16 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "#ATOMIC_LOAD_NAND_I16",
[(set GPRC:$dst, (atomic_load_nand_16 xoaddr:$ptr, GPRC:$incr))]>;
def ATOMIC_LOAD_ADD_I32 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "#ATOMIC_LOAD_ADD_I32",
[(set GPRC:$dst, (atomic_load_add_32 xoaddr:$ptr, GPRC:$incr))]>;
def ATOMIC_LOAD_SUB_I32 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "#ATOMIC_LOAD_SUB_I32",
[(set GPRC:$dst, (atomic_load_sub_32 xoaddr:$ptr, GPRC:$incr))]>;
def ATOMIC_LOAD_AND_I32 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "#ATOMIC_LOAD_AND_I32",
[(set GPRC:$dst, (atomic_load_and_32 xoaddr:$ptr, GPRC:$incr))]>;
def ATOMIC_LOAD_OR_I32 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "#ATOMIC_LOAD_OR_I32",
[(set GPRC:$dst, (atomic_load_or_32 xoaddr:$ptr, GPRC:$incr))]>;
def ATOMIC_LOAD_XOR_I32 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "#ATOMIC_LOAD_XOR_I32",
[(set GPRC:$dst, (atomic_load_xor_32 xoaddr:$ptr, GPRC:$incr))]>;
def ATOMIC_LOAD_NAND_I32 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr), "#ATOMIC_LOAD_NAND_I32",
[(set GPRC:$dst, (atomic_load_nand_32 xoaddr:$ptr, GPRC:$incr))]>;
def ATOMIC_CMP_SWAP_I8 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$old, GPRC:$new), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$old, GPRC:$new), "#ATOMIC_CMP_SWAP_I8",
[(set GPRC:$dst,
(atomic_cmp_swap_8 xoaddr:$ptr, GPRC:$old, GPRC:$new))]>;
def ATOMIC_CMP_SWAP_I16 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$old, GPRC:$new), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$old, GPRC:$new), "#ATOMIC_CMP_SWAP_I16 $dst $ptr $old $new",
[(set GPRC:$dst,
(atomic_cmp_swap_16 xoaddr:$ptr, GPRC:$old, GPRC:$new))]>;
def ATOMIC_CMP_SWAP_I32 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$old, GPRC:$new), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$old, GPRC:$new), "#ATOMIC_CMP_SWAP_I32 $dst $ptr $old $new",
[(set GPRC:$dst,
(atomic_cmp_swap_32 xoaddr:$ptr, GPRC:$old, GPRC:$new))]>;
def ATOMIC_SWAP_I8 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$new), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$new), "#ATOMIC_SWAP_i8",
[(set GPRC:$dst, (atomic_swap_8 xoaddr:$ptr, GPRC:$new))]>;
def ATOMIC_SWAP_I16 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$new), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$new), "#ATOMIC_SWAP_I16",
[(set GPRC:$dst, (atomic_swap_16 xoaddr:$ptr, GPRC:$new))]>;
def ATOMIC_SWAP_I32 : Pseudo<
- (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$new), "",
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$new), "#ATOMIC_SWAP_I32",
[(set GPRC:$dst, (atomic_swap_32 xoaddr:$ptr, GPRC:$new))]>;
}
}
@@ -1207,7 +1208,7 @@ def MTCRF : XFXForm_5<31, 144, (outs crbitm:$FXM), (ins GPRC:$rS),
//
// FIXME: Make this a real Pseudo instruction when the JIT switches to MC.
def MFCRpseud: XFXForm_3<31, 19, (outs GPRC:$rT), (ins crbitm:$FXM),
- "", SprMFCR>,
+ "#MFCRpseud", SprMFCR>,
PPC970_MicroCode, PPC970_Unit_CRU;
def MFCR : XFXForm_3<31, 19, (outs GPRC:$rT), (ins),
diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp
index 1665d7313c..459c3589d3 100644
--- a/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -596,7 +596,7 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
// to Offset to get the correct offset.
// Naked functions have stack size 0, although getStackSize may not reflect that
// because we didn't call all the pieces that compute it for naked functions.
- if (!MF.getFunction()->getFnAttributes().hasNakedAttr())
+ if (!MF.getFunction()->getFnAttributes().hasAttribute(Attributes::Naked))
Offset += MFI->getStackSize();
// If we can, encode the offset directly into the instruction. If this is a
diff --git a/lib/Target/PowerPC/PPCSubtarget.cpp b/lib/Target/PowerPC/PPCSubtarget.cpp
index bb193ac3d9..14b8534d1c 100644
--- a/lib/Target/PowerPC/PPCSubtarget.cpp
+++ b/lib/Target/PowerPC/PPCSubtarget.cpp
@@ -66,7 +66,7 @@ PPCSubtarget::PPCSubtarget(const std::string &TT, const std::string &CPU,
// Silently force 64-bit register use on ppc64.
Use64BitRegs = true;
}
-
+
// If the user requested use of 64-bit regs, but the cpu selected doesn't
// support it, ignore.
if (use64BitRegs() && !has64BitSupport())
diff --git a/lib/Target/PowerPC/PPCSubtarget.h b/lib/Target/PowerPC/PPCSubtarget.h
index b8b1614e62..c20995afe8 100644
--- a/lib/Target/PowerPC/PPCSubtarget.h
+++ b/lib/Target/PowerPC/PPCSubtarget.h
@@ -108,9 +108,9 @@ public:
/// selection.
const InstrItineraryData &getInstrItineraryData() const { return InstrItins; }
- /// getTargetDataString - Return the pointer size and type alignment
+ /// getDataLayoutString - Return the pointer size and type alignment
/// properties of this subtarget.
- const char *getTargetDataString() const {
+ const char *getDataLayoutString() const {
// Note, the alignment values for f64 and i64 on ppc64 in Darwin
// documentation are wrong; these are correct (i.e. "what gcc does").
return isPPC64() ? "E-p:64:64-f64:64:64-i64:64:64-f128:64:128-n32:64"
diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp
index 980511268a..5f39b8d2c2 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.cpp
+++ b/lib/Target/PowerPC/PPCTargetMachine.cpp
@@ -40,7 +40,7 @@ PPCTargetMachine::PPCTargetMachine(const Target &T, StringRef TT,
bool is64Bit)
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
Subtarget(TT, CPU, FS, is64Bit),
- DataLayout(Subtarget.getTargetDataString()), InstrInfo(*this),
+ DL(Subtarget.getDataLayoutString()), InstrInfo(*this),
FrameLowering(Subtarget), JITInfo(*this, is64Bit),
TLInfo(*this), TSInfo(*this),
InstrItins(Subtarget.getInstrItineraryData()) {
diff --git a/lib/Target/PowerPC/PPCTargetMachine.h b/lib/Target/PowerPC/PPCTargetMachine.h
index 7da2b0cb10..02d69fd15d 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.h
+++ b/lib/Target/PowerPC/PPCTargetMachine.h
@@ -21,7 +21,7 @@
#include "PPCISelLowering.h"
#include "PPCSelectionDAGInfo.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
namespace llvm {
@@ -29,7 +29,7 @@ namespace llvm {
///
class PPCTargetMachine : public LLVMTargetMachine {
PPCSubtarget Subtarget;
- const TargetData DataLayout; // Calculates type size & alignment
+ const DataLayout DL; // Calculates type size & alignment
PPCInstrInfo InstrInfo;
PPCFrameLowering FrameLowering;
PPCJITInfo JITInfo;
@@ -58,7 +58,7 @@ public:
return &InstrInfo.getRegisterInfo();
}
- virtual const TargetData *getTargetData() const { return &DataLayout; }
+ virtual const DataLayout *getDataLayout() const { return &DL; }
virtual const PPCSubtarget *getSubtargetImpl() const { return &Subtarget; }
virtual const InstrItineraryData *getInstrItineraryData() const {
return &InstrItins;
diff --git a/lib/Target/README.txt b/lib/Target/README.txt
index 9c27f27696..8165f5b8cc 100644
--- a/lib/Target/README.txt
+++ b/lib/Target/README.txt
@@ -152,7 +152,7 @@ stuff too.
//===---------------------------------------------------------------------===//
-For vector types, TargetData.cpp::getTypeInfo() returns alignment that is equal
+For vector types, DataLayout.cpp::getTypeInfo() returns alignment that is equal
to the type size. It works but can be overly conservative as the alignment of
specific vector types are target dependent.
diff --git a/lib/Target/Sparc/SparcFrameLowering.cpp b/lib/Target/Sparc/SparcFrameLowering.cpp
index 1c5c89e971..716c79f43a 100644
--- a/lib/Target/Sparc/SparcFrameLowering.cpp
+++ b/lib/Target/Sparc/SparcFrameLowering.cpp
@@ -20,7 +20,7 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/CommandLine.h"
diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp
index 79f7ebd82d..8e5619e6bc 100644
--- a/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/lib/Target/Sparc/SparcISelLowering.cpp
@@ -637,7 +637,7 @@ SparcTargetLowering::getSRetArgSize(SelectionDAG &DAG, SDValue Callee) const
PointerType *Ty = cast<PointerType>(CalleeFn->arg_begin()->getType());
Type *ElementTy = Ty->getElementType();
- return getTargetData()->getTypeAllocSize(ElementTy);
+ return getDataLayout()->getTypeAllocSize(ElementTy);
}
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/Sparc/SparcTargetMachine.cpp b/lib/Target/Sparc/SparcTargetMachine.cpp
index 9ee12ed7f5..8b7559c2f9 100644
--- a/lib/Target/Sparc/SparcTargetMachine.cpp
+++ b/lib/Target/Sparc/SparcTargetMachine.cpp
@@ -33,7 +33,7 @@ SparcTargetMachine::SparcTargetMachine(const Target &T, StringRef TT,
bool is64bit)
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
Subtarget(TT, CPU, FS, is64bit),
- DataLayout(Subtarget.getDataLayout()),
+ DL(Subtarget.getDataLayout()),
InstrInfo(Subtarget),
TLInfo(*this), TSInfo(*this),
FrameLowering(Subtarget) {
diff --git a/lib/Target/Sparc/SparcTargetMachine.h b/lib/Target/Sparc/SparcTargetMachine.h
index b2cc624e45..c9f2d68eb1 100644
--- a/lib/Target/Sparc/SparcTargetMachine.h
+++ b/lib/Target/Sparc/SparcTargetMachine.h
@@ -20,14 +20,14 @@
#include "SparcSelectionDAGInfo.h"
#include "SparcSubtarget.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetFrameLowering.h"
namespace llvm {
class SparcTargetMachine : public LLVMTargetMachine {
SparcSubtarget Subtarget;
- const TargetData DataLayout; // Calculates type size & alignment
+ const DataLayout DL; // Calculates type size & alignment
SparcInstrInfo InstrInfo;
SparcTargetLowering TLInfo;
SparcSelectionDAGInfo TSInfo;
@@ -52,7 +52,7 @@ public:
virtual const SparcSelectionDAGInfo* getSelectionDAGInfo() const {
return &TSInfo;
}
- virtual const TargetData *getTargetData() const { return &DataLayout; }
+ virtual const DataLayout *getDataLayout() const { return &DL; }
// Pass Pipeline Configuration
virtual TargetPassConfig *createPassConfig(PassManagerBase &PM);
diff --git a/lib/Target/Target.cpp b/lib/Target/Target.cpp
index a2b83bcce4..b0b5c875b8 100644
--- a/lib/Target/Target.cpp
+++ b/lib/Target/Target.cpp
@@ -16,7 +16,7 @@
#include "llvm-c/Initialization.h"
#include "llvm/InitializePasses.h"
#include "llvm/PassManager.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/LLVMContext.h"
#include <cstring>
@@ -24,7 +24,7 @@
using namespace llvm;
void llvm::initializeTarget(PassRegistry &Registry) {
- initializeTargetDataPass(Registry);
+ initializeDataLayoutPass(Registry);
initializeTargetLibraryInfoPass(Registry);
}
@@ -33,11 +33,11 @@ void LLVMInitializeTarget(LLVMPassRegistryRef R) {
}
LLVMTargetDataRef LLVMCreateTargetData(const char *StringRep) {
- return wrap(new TargetData(StringRep));
+ return wrap(new DataLayout(StringRep));
}
void LLVMAddTargetData(LLVMTargetDataRef TD, LLVMPassManagerRef PM) {
- unwrap(PM)->add(new TargetData(*unwrap(TD)));
+ unwrap(PM)->add(new DataLayout(*unwrap(TD)));
}
void LLVMAddTargetLibraryInfo(LLVMTargetLibraryInfoRef TLI,
diff --git a/lib/Target/TargetELFWriterInfo.cpp b/lib/Target/TargetELFWriterInfo.cpp
index a661ee9c0c..66da391eca 100644
--- a/lib/Target/TargetELFWriterInfo.cpp
+++ b/lib/Target/TargetELFWriterInfo.cpp
@@ -13,7 +13,7 @@
#include "llvm/Function.h"
#include "llvm/Target/TargetELFWriterInfo.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp
index b74a0bd25d..9d7e2b825f 100644
--- a/lib/Target/TargetLoweringObjectFile.cpp
+++ b/lib/Target/TargetLoweringObjectFile.cpp
@@ -22,7 +22,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Dwarf.h"
@@ -184,7 +184,7 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV,
// Otherwise, just drop it into a mergable constant section. If we have
// a section for this size, use it, otherwise use the arbitrary sized
// mergable section.
- switch (TM.getTargetData()->getTypeAllocSize(C->getType())) {
+ switch (TM.getDataLayout()->getTypeAllocSize(C->getType())) {
case 4: return SectionKind::getMergeableConst4();
case 8: return SectionKind::getMergeableConst8();
case 16: return SectionKind::getMergeableConst16();
diff --git a/lib/Target/TargetMachineC.cpp b/lib/Target/TargetMachineC.cpp
index d6bba8b0dd..f69c2abd50 100644
--- a/lib/Target/TargetMachineC.cpp
+++ b/lib/Target/TargetMachineC.cpp
@@ -14,7 +14,7 @@
#include "llvm-c/Core.h"
#include "llvm-c/Target.h"
#include "llvm-c/TargetMachine.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
@@ -146,7 +146,7 @@ char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) {
}
LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T) {
- return wrap(unwrap(T)->getTargetData());
+ return wrap(unwrap(T)->getDataLayout());
}
LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
@@ -158,14 +158,14 @@ LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
std::string error;
- const TargetData* td = TM->getTargetData();
+ const DataLayout* td = TM->getDataLayout();
if (!td) {
- error = "No TargetData in TargetMachine";
+ error = "No DataLayout in TargetMachine";
*ErrorMessage = strdup(error.c_str());
return true;
}
- pass.add(new TargetData(*td));
+ pass.add(new DataLayout(*td));
TargetMachine::CodeGenFileType ft;
switch (codegen) {
@@ -184,7 +184,7 @@ LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
}
if (TM->addPassesToEmitFile(pass, destf, ft)) {
- error = "No TargetData in TargetMachine";
+ error = "No DataLayout in TargetMachine";
*ErrorMessage = strdup(error.c_str());
return true;
}
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 9263bdde20..df34359a66 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -53,7 +53,7 @@ private:
X86Operand *ParseOperand();
X86Operand *ParseATTOperand();
X86Operand *ParseIntelOperand();
- X86Operand *ParseIntelMemOperand();
+ X86Operand *ParseIntelMemOperand(unsigned SegReg, SMLoc StartLoc);
X86Operand *ParseIntelBracExpression(unsigned SegReg, unsigned Size);
X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
@@ -66,12 +66,11 @@ private:
bool MatchAndEmitInstruction(SMLoc IDLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCStreamer &Out);
-
- bool MatchInstruction(SMLoc IDLoc, unsigned &Kind,
+ bool MatchInstruction(SMLoc IDLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
- SmallVectorImpl<MCInst> &MCInsts,
- unsigned &OrigErrorInfo,
- bool matchingInlineAsm = false);
+ MCStreamer &Out, unsigned &Kind, unsigned &Opcode,
+ MatchInstMapAndConstraintsImpl &MapAndConstraints,
+ unsigned &OrigErrorInfo, bool matchingInlineAsm = false);
/// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi)
/// in 64bit mode or (%esi) or %es:(%esi) in 32bit mode.
@@ -730,10 +729,9 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
}
/// ParseIntelMemOperand - Parse intel style memory operand.
-X86Operand *X86AsmParser::ParseIntelMemOperand() {
+X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg, SMLoc Start) {
const AsmToken &Tok = Parser.getTok();
- SMLoc Start = Parser.getTok().getLoc(), End;
- unsigned SegReg = 0;
+ SMLoc End;
unsigned Size = getIntelMemOperandSize(Tok.getString());
if (Size) {
@@ -777,12 +775,17 @@ X86Operand *X86AsmParser::ParseIntelOperand() {
// register
unsigned RegNo = 0;
if (!ParseRegister(RegNo, Start, End)) {
- End = Parser.getTok().getLoc();
- return X86Operand::CreateReg(RegNo, Start, End);
+ // If this is a segment register followed by a ':', then this is the start
+ // of a memory reference, otherwise this is a normal register reference.
+ if (getLexer().isNot(AsmToken::Colon))
+ return X86Operand::CreateReg(RegNo, Start, Parser.getTok().getLoc());
+
+ getParser().Lex(); // Eat the colon.
+ return ParseIntelMemOperand(RegNo, Start);
}
// mem operand
- return ParseIntelMemOperand();
+ return ParseIntelMemOperand(0, Start);
}
X86Operand *X86AsmParser::ParseATTOperand() {
@@ -1521,22 +1524,20 @@ MatchAndEmitInstruction(SMLoc IDLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCStreamer &Out) {
unsigned Kind;
+ unsigned Opcode;
unsigned ErrorInfo;
- SmallVector<MCInst, 2> Insts;
-
- bool Error = MatchInstruction(IDLoc, Kind, Operands, Insts,
- ErrorInfo);
- if (!Error)
- for (unsigned i = 0, e = Insts.size(); i != e; ++i)
- Out.EmitInstruction(Insts[i]);
+ MatchInstMapAndConstraints MapAndConstraints;
+ bool Error = MatchInstruction(IDLoc, Operands, Out, Kind, Opcode,
+ MapAndConstraints, ErrorInfo);
return Error;
}
bool X86AsmParser::
-MatchInstruction(SMLoc IDLoc, unsigned &Kind,
+MatchInstruction(SMLoc IDLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
- SmallVectorImpl<MCInst> &MCInsts, unsigned &OrigErrorInfo,
- bool matchingInlineAsm) {
+ MCStreamer &Out, unsigned &Kind, unsigned &Opcode,
+ SmallVectorImpl<std::pair< unsigned, std::string > > &MapAndConstraints,
+ unsigned &OrigErrorInfo, bool matchingInlineAsm) {
assert(!Operands.empty() && "Unexpect empty operand list!");
X86Operand *Op = static_cast<X86Operand*>(Operands[0]);
assert(Op->isToken() && "Leading operand should always be a mnemonic!");
@@ -1553,7 +1554,8 @@ MatchInstruction(SMLoc IDLoc, unsigned &Kind,
MCInst Inst;
Inst.setOpcode(X86::WAIT);
Inst.setLoc(IDLoc);
- MCInsts.push_back(Inst);
+ if (!matchingInlineAsm)
+ Out.EmitInstruction(Inst);
const char *Repl =
StringSwitch<const char*>(Op->getToken())
@@ -1575,18 +1577,22 @@ MatchInstruction(SMLoc IDLoc, unsigned &Kind,
MCInst Inst;
// First, try a direct match.
- switch (MatchInstructionImpl(Operands, Kind, Inst, OrigErrorInfo,
+ switch (MatchInstructionImpl(Operands, Kind, Inst, MapAndConstraints,
+ OrigErrorInfo, matchingInlineAsm,
isParsingIntelSyntax())) {
default: break;
case Match_Success:
// Some instructions need post-processing to, for example, tweak which
// encoding is selected. Loop on it while changes happen so the
// individual transformations can chain off each other.
- while (processInstruction(Inst, Operands))
- ;
+ if (!matchingInlineAsm)
+ while (processInstruction(Inst, Operands))
+ ;
Inst.setLoc(IDLoc);
- MCInsts.push_back(Inst);
+ if (!matchingInlineAsm)
+ Out.EmitInstruction(Inst);
+ Opcode = Inst.getOpcode();
return false;
case Match_MissingFeature:
Error(IDLoc, "instruction requires a CPU feature not currently enabled",
@@ -1625,20 +1631,21 @@ MatchInstruction(SMLoc IDLoc, unsigned &Kind,
unsigned Match1, Match2, Match3, Match4;
unsigned tKind;
- Match1 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore,
- isParsingIntelSyntax());
+ MatchInstMapAndConstraints tMapAndConstraints[4];
+ Match1 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[0],
+ ErrorInfoIgnore, isParsingIntelSyntax());
if (Match1 == Match_Success) Kind = tKind;
Tmp[Base.size()] = Suffixes[1];
- Match2 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore,
- isParsingIntelSyntax());
+ Match2 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[1],
+ ErrorInfoIgnore, isParsingIntelSyntax());
if (Match2 == Match_Success) Kind = tKind;
Tmp[Base.size()] = Suffixes[2];
- Match3 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore,
- isParsingIntelSyntax());
+ Match3 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[2],
+ ErrorInfoIgnore, isParsingIntelSyntax());
if (Match3 == Match_Success) Kind = tKind;
Tmp[Base.size()] = Suffixes[3];
- Match4 = MatchInstructionImpl(Operands, tKind, Inst, ErrorInfoIgnore,
- isParsingIntelSyntax());
+ Match4 = MatchInstructionImpl(Operands, tKind, Inst, tMapAndConstraints[3],
+ ErrorInfoIgnore, isParsingIntelSyntax());
if (Match4 == Match_Success) Kind = tKind;
// Restore the old token.
@@ -1652,7 +1659,10 @@ MatchInstruction(SMLoc IDLoc, unsigned &Kind,
(Match3 == Match_Success) + (Match4 == Match_Success);
if (NumSuccessfulMatches == 1) {
Inst.setLoc(IDLoc);
- MCInsts.push_back(Inst);
+ if (!matchingInlineAsm)
+ Out.EmitInstruction(Inst);
+ Opcode = Inst.getOpcode();
+ // FIXME: Handle the map and constraints.
return false;
}
diff --git a/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp b/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp
index b123afa001..149be86fe8 100644
--- a/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp
+++ b/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp
@@ -59,7 +59,8 @@ void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
void X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op,
raw_ostream &O) {
- switch (MI->getOperand(Op).getImm()) {
+ int64_t Imm = MI->getOperand(Op).getImm() & 0xf;
+ switch (Imm) {
default: llvm_unreachable("Invalid ssecc argument!");
case 0: O << "eq"; break;
case 1: O << "lt"; break;
@@ -77,6 +78,30 @@ void X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op,
case 0xd: O << "ge"; break;
case 0xe: O << "gt"; break;
case 0xf: O << "true"; break;
+ }
+}
+
+void X86ATTInstPrinter::printAVXCC(const MCInst *MI, unsigned Op,
+ raw_ostream &O) {
+ int64_t Imm = MI->getOperand(Op).getImm() & 0x1f;
+ switch (Imm) {
+ default: llvm_unreachable("Invalid avxcc argument!");
+ case 0: O << "eq"; break;
+ case 1: O << "lt"; break;
+ case 2: O << "le"; break;
+ case 3: O << "unord"; break;
+ case 4: O << "neq"; break;
+ case 5: O << "nlt"; break;
+ case 6: O << "nle"; break;
+ case 7: O << "ord"; break;
+ case 8: O << "eq_uq"; break;
+ case 9: O << "nge"; break;
+ case 0xa: O << "ngt"; break;
+ case 0xb: O << "false"; break;
+ case 0xc: O << "neq_oq"; break;
+ case 0xd: O << "ge"; break;
+ case 0xe: O << "gt"; break;
+ case 0xf: O << "true"; break;
case 0x10: O << "eq_os"; break;
case 0x11: O << "lt_oq"; break;
case 0x12: O << "le_oq"; break;
diff --git a/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h b/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h
index 09a7a7c421..8e09183dcc 100644
--- a/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h
+++ b/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h
@@ -40,6 +40,7 @@ public:
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &OS);
void printMemReference(const MCInst *MI, unsigned Op, raw_ostream &OS);
void printSSECC(const MCInst *MI, unsigned Op, raw_ostream &OS);
+ void printAVXCC(const MCInst *MI, unsigned Op, raw_ostream &OS);
void printPCRelImm(const MCInst *MI, unsigned OpNo, raw_ostream &OS);
void printopaquemem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
diff --git a/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp b/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp
index f9bb3be9d7..d67aec7f10 100644
--- a/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp
+++ b/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp
@@ -1,4 +1,4 @@
-//===-- X86IntelInstPrinter.cpp - AT&T assembly instruction printing ------===//
+//===-- X86IntelInstPrinter.cpp - Intel assembly instruction printing -----===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file includes code for rendering MCInst instances as AT&T-style
+// This file includes code for rendering MCInst instances as Intel-style
// assembly.
//
//===----------------------------------------------------------------------===//
@@ -51,7 +51,8 @@ void X86IntelInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
void X86IntelInstPrinter::printSSECC(const MCInst *MI, unsigned Op,
raw_ostream &O) {
- switch (MI->getOperand(Op).getImm()) {
+ int64_t Imm = MI->getOperand(Op).getImm() & 0xf;
+ switch (Imm) {
default: llvm_unreachable("Invalid ssecc argument!");
case 0: O << "eq"; break;
case 1: O << "lt"; break;
@@ -69,6 +70,30 @@ void X86IntelInstPrinter::printSSECC(const MCInst *MI, unsigned Op,
case 0xd: O << "ge"; break;
case 0xe: O << "gt"; break;
case 0xf: O << "true"; break;
+ }
+}
+
+void X86IntelInstPrinter::printAVXCC(const MCInst *MI, unsigned Op,
+ raw_ostream &O) {
+ int64_t Imm = MI->getOperand(Op).getImm() & 0x1f;
+ switch (Imm) {
+ default: llvm_unreachable("Invalid avxcc argument!");
+ case 0: O << "eq"; break;
+ case 1: O << "lt"; break;
+ case 2: O << "le"; break;
+ case 3: O << "unord"; break;
+ case 4: O << "neq"; break;
+ case 5: O << "nlt"; break;
+ case 6: O << "nle"; break;
+ case 7: O << "ord"; break;
+ case 8: O << "eq_uq"; break;
+ case 9: O << "nge"; break;
+ case 0xa: O << "ngt"; break;
+ case 0xb: O << "false"; break;
+ case 0xc: O << "neq_oq"; break;
+ case 0xd: O << "ge"; break;
+ case 0xe: O << "gt"; break;
+ case 0xf: O << "true"; break;
case 0x10: O << "eq_os"; break;
case 0x11: O << "lt_oq"; break;
case 0x12: O << "le_oq"; break;
@@ -85,7 +110,6 @@ void X86IntelInstPrinter::printSSECC(const MCInst *MI, unsigned Op,
case 0x1d: O << "ge_oq"; break;
case 0x1e: O << "gt_oq"; break;
case 0x1f: O << "true_us"; break;
-
}
}
@@ -160,8 +184,7 @@ void X86IntelInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
printOperand(MI, Op+2, O);
NeedPlus = true;
}
-
-
+
if (!DispSpec.isImm()) {
if (NeedPlus) O << " + ";
assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
diff --git a/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h b/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h
index 04c83d5eec..bb769eb52e 100644
--- a/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h
+++ b/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This class prints an X86 MCInst to intel style .s file syntax.
+// This class prints an X86 MCInst to Intel style .s file syntax.
//
//===----------------------------------------------------------------------===//
@@ -37,6 +37,7 @@ public:
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
void printMemReference(const MCInst *MI, unsigned Op, raw_ostream &O);
void printSSECC(const MCInst *MI, unsigned Op, raw_ostream &O);
+ void printAVXCC(const MCInst *MI, unsigned Op, raw_ostream &O);
void printPCRelImm(const MCInst *MI, unsigned OpNo, raw_ostream &O);
void printopaquemem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
diff --git a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index 2696190d23..9bac1eb7c0 100644
--- a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -473,7 +473,7 @@ MCAsmBackend *llvm::createX86_32AsmBackend(const Target &T, StringRef TT, String
if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO)
return new DarwinX86_32AsmBackend(T, CPU);
- if (TheTriple.isOSWindows())
+ if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF)
return new WindowsX86AsmBackend(T, false, CPU);
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
@@ -486,7 +486,7 @@ MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T, StringRef TT, String
if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO)
return new DarwinX86_64AsmBackend(T, CPU);
- if (TheTriple.isOSWindows())
+ if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF)
return new WindowsX86AsmBackend(T, true, CPU);
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index 06138bf335..400263c3b5 100644
--- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -16,6 +16,7 @@
#include "MCTargetDesc/X86BaseInfo.h"
#include "MCTargetDesc/X86FixupKinds.h"
#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
@@ -51,8 +52,8 @@ public:
return (STI.getFeatureBits() & X86::Mode64Bit) == 0;
}
- static unsigned GetX86RegNum(const MCOperand &MO) {
- return X86_MC::getX86RegNum(MO.getReg());
+ unsigned GetX86RegNum(const MCOperand &MO) const {
+ return Ctx.getRegisterInfo().getEncodingValue(MO.getReg()) & 0x7;
}
// On regular x86, both XMM0-XMM7 and XMM8-XMM15 are encoded in the range
@@ -64,8 +65,8 @@ public:
// VEX.VVVV => XMM9 => ~9
//
// See table 4-35 of Intel AVX Programming Reference for details.
- static unsigned char getVEXRegisterEncoding(const MCInst &MI,
- unsigned OpNum) {
+ unsigned char getVEXRegisterEncoding(const MCInst &MI,
+ unsigned OpNum) const {
unsigned SrcReg = MI.getOperand(OpNum).getReg();
unsigned SrcRegNum = GetX86RegNum(MI.getOperand(OpNum));
if (X86II::isX86_64ExtendedReg(SrcReg))
diff --git a/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
index 348236316c..287c9f137a 100644
--- a/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
+++ b/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
@@ -209,117 +209,10 @@ unsigned X86_MC::getDwarfRegFlavour(StringRef TT, bool isEH) {
return DWARFFlavour::X86_32_Generic;
}
-/// getX86RegNum - This function maps LLVM register identifiers to their X86
-/// specific numbering, which is used in various places encoding instructions.
-unsigned X86_MC::getX86RegNum(unsigned RegNo) {
- switch(RegNo) {
- case X86::RAX: case X86::EAX: case X86::AX: case X86::AL: return N86::EAX;
- case X86::RCX: case X86::ECX: case X86::CX: case X86::CL: return N86::ECX;
- case X86::RDX: case X86::EDX: case X86::DX: case X86::DL: return N86::EDX;
- case X86::RBX: case X86::EBX: case X86::BX: case X86::BL: return N86::EBX;
- case X86::RSP: case X86::ESP: case X86::SP: case X86::SPL: case X86::AH:
- return N86::ESP;
- case X86::RBP: case X86::EBP: case X86::BP: case X86::BPL: case X86::CH:
- return N86::EBP;
- case X86::RSI: case X86::ESI: case X86::SI: case X86::SIL: case X86::DH:
- return N86::ESI;
- case X86::RDI: case X86::EDI: case X86::DI: case X86::DIL: case X86::BH:
- return N86::EDI;
-
- case X86::R8: case X86::R8D: case X86::R8W: case X86::R8B:
- return N86::EAX;
- case X86::R9: case X86::R9D: case X86::R9W: case X86::R9B:
- return N86::ECX;
- case X86::R10: case X86::R10D: case X86::R10W: case X86::R10B:
- return N86::EDX;
- case X86::R11: case X86::R11D: case X86::R11W: case X86::R11B:
- return N86::EBX;
- case X86::R12: case X86::R12D: case X86::R12W: case X86::R12B:
- return N86::ESP;
- case X86::R13: case X86::R13D: case X86::R13W: case X86::R13B:
- return N86::EBP;
- case X86::R14: case X86::R14D: case X86::R14W: case X86::R14B:
- return N86::ESI;
- case X86::R15: case X86::R15D: case X86::R15W: case X86::R15B:
- return N86::EDI;
-
- case X86::ST0: case X86::ST1: case X86::ST2: case X86::ST3:
- case X86::ST4: case X86::ST5: case X86::ST6: case X86::ST7:
- return RegNo-X86::ST0;
-
- case X86::XMM0: case X86::XMM8:
- case X86::YMM0: case X86::YMM8: case X86::MM0:
- return 0;
- case X86::XMM1: case X86::XMM9:
- case X86::YMM1: case X86::YMM9: case X86::MM1:
- return 1;
- case X86::XMM2: case X86::XMM10:
- case X86::YMM2: case X86::YMM10: case X86::MM2:
- return 2;
- case X86::XMM3: case X86::XMM11:
- case X86::YMM3: case X86::YMM11: case X86::MM3:
- return 3;
- case X86::XMM4: case X86::XMM12:
- case X86::YMM4: case X86::YMM12: case X86::MM4:
- return 4;
- case X86::XMM5: case X86::XMM13:
- case X86::YMM5: case X86::YMM13: case X86::MM5:
- return 5;
- case X86::XMM6: case X86::XMM14:
- case X86::YMM6: case X86::YMM14: case X86::MM6:
- return 6;
- case X86::XMM7: case X86::XMM15:
- case X86::YMM7: case X86::YMM15: case X86::MM7:
- return 7;
-
- case X86::ES: return 0;
- case X86::CS: return 1;
- case X86::SS: return 2;
- case X86::DS: return 3;
- case X86::FS: return 4;
- case X86::GS: return 5;
-
- case X86::CR0: case X86::CR8 : case X86::DR0: return 0;
- case X86::CR1: case X86::CR9 : case X86::DR1: return 1;
- case X86::CR2: case X86::CR10: case X86::DR2: return 2;
- case X86::CR3: case X86::CR11: case X86::DR3: return 3;
- case X86::CR4: case X86::CR12: case X86::DR4: return 4;
- case X86::CR5: case X86::CR13: case X86::DR5: return 5;
- case X86::CR6: case X86::CR14: case X86::DR6: return 6;
- case X86::CR7: case X86::CR15: case X86::DR7: return 7;
-
- // Pseudo index registers are equivalent to a "none"
- // scaled index (See Intel Manual 2A, table 2-3)
- case X86::EIZ:
- case X86::RIZ:
- return 4;
-
- default:
- assert((int(RegNo) > 0) && "Unknown physical register!");
- return 0;
- }
-}
-
void X86_MC::InitLLVM2SEHRegisterMapping(MCRegisterInfo *MRI) {
// FIXME: TableGen these.
for (unsigned Reg = X86::NoRegister+1; Reg < X86::NUM_TARGET_REGS; ++Reg) {
- int SEH = X86_MC::getX86RegNum(Reg);
- switch (Reg) {
- case X86::R8: case X86::R8D: case X86::R8W: case X86::R8B:
- case X86::R9: case X86::R9D: case X86::R9W: case X86::R9B:
- case X86::R10: case X86::R10D: case X86::R10W: case X86::R10B:
- case X86::R11: case X86::R11D: case X86::R11W: case X86::R11B:
- case X86::R12: case X86::R12D: case X86::R12W: case X86::R12B:
- case X86::R13: case X86::R13D: case X86::R13W: case X86::R13B:
- case X86::R14: case X86::R14D: case X86::R14W: case X86::R14B:
- case X86::R15: case X86::R15D: case X86::R15W: case X86::R15B:
- case X86::XMM8: case X86::XMM9: case X86::XMM10: case X86::XMM11:
- case X86::XMM12: case X86::XMM13: case X86::XMM14: case X86::XMM15:
- case X86::YMM8: case X86::YMM9: case X86::YMM10: case X86::YMM11:
- case X86::YMM12: case X86::YMM13: case X86::YMM14: case X86::YMM15:
- SEH += 8;
- break;
- }
+ unsigned SEH = MRI->getEncodingValue(Reg);
MRI->mapLLVMRegToSEHReg(Reg, SEH);
}
}
@@ -379,11 +272,15 @@ static MCAsmInfo *createX86MCAsmInfo(const Target &T, StringRef TT) {
MAI = new X86_64MCAsmInfoDarwin(TheTriple);
else
MAI = new X86MCAsmInfoDarwin(TheTriple);
+ } else if (TheTriple.getEnvironment() == Triple::ELF) {
+ // Force the use of an ELF container.
+ MAI = new X86ELFMCAsmInfo(TheTriple);
} else if (TheTriple.getOS() == Triple::Win32) {
MAI = new X86MCAsmInfoMicrosoft(TheTriple);
} else if (TheTriple.getOS() == Triple::MinGW32 || TheTriple.getOS() == Triple::Cygwin) {
MAI = new X86MCAsmInfoGNUCOFF(TheTriple);
} else {
+ // The default is ELF.
MAI = new X86ELFMCAsmInfo(TheTriple);
}
@@ -465,7 +362,7 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO)
return createMachOStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll);
- if (TheTriple.isOSWindows())
+ if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF)
return createWinCOFFStreamer(Ctx, MAB, *_Emitter, _OS, RelaxAll);
return createELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack);
diff --git a/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h b/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h
index 4b0cacecfa..0b0989bff1 100644
--- a/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h
+++ b/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h
@@ -64,8 +64,6 @@ namespace X86_MC {
unsigned getDwarfRegFlavour(StringRef TT, bool isEH);
- unsigned getX86RegNum(unsigned RegNo);
-
void InitLLVM2SEHRegisterMapping(MCRegisterInfo *MRI);
/// createX86MCSubtargetInfo - Create a X86 MCSubtargetInfo instance.
diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td
index def0f16e96..1dc4aa9989 100644
--- a/lib/Target/X86/X86.td
+++ b/lib/Target/X86/X86.td
@@ -121,8 +121,8 @@ def FeatureBMI2 : SubtargetFeature<"bmi2", "HasBMI2", "true",
def FeatureLeaForSP : SubtargetFeature<"lea-sp", "UseLeaForSP", "true",
"Use LEA for adjusting the stack pointer">;
def FeatureSlowDivide : SubtargetFeature<"idiv-to-divb",
- "HasSlowDivide", "true",
- "Use small divide for positive values less than 256">;
+ "HasSlowDivide", "true",
+ "Use small divide for positive values less than 256">;
//===----------------------------------------------------------------------===//
// X86 processors supported.
diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp
index 8c6696c64d..47ffd8b3ef 100644
--- a/lib/Target/X86/X86AsmPrinter.cpp
+++ b/lib/Target/X86/X86AsmPrinter.cpp
@@ -272,7 +272,7 @@ void X86AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
if (AsmVariant == 0) O << '%';
unsigned Reg = MO.getReg();
if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) {
- EVT VT = (strcmp(Modifier+6,"64") == 0) ?
+ MVT::SimpleValueType VT = (strcmp(Modifier+6,"64") == 0) ?
MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 :
((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8));
Reg = getX86SubSuperRegister(Reg, VT);
@@ -296,46 +296,6 @@ void X86AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
}
}
-void X86AsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op,
- raw_ostream &O) {
- unsigned char value = MI->getOperand(Op).getImm();
- switch (value) {
- default: llvm_unreachable("Invalid ssecc argument!");
- case 0: O << "eq"; break;
- case 1: O << "lt"; break;
- case 2: O << "le"; break;
- case 3: O << "unord"; break;
- case 4: O << "neq"; break;
- case 5: O << "nlt"; break;
- case 6: O << "nle"; break;
- case 7: O << "ord"; break;
- case 8: O << "eq_uq"; break;
- case 9: O << "nge"; break;
- case 0xa: O << "ngt"; break;
- case 0xb: O << "false"; break;
- case 0xc: O << "neq_oq"; break;
- case 0xd: O << "ge"; break;
- case 0xe: O << "gt"; break;
- case 0xf: O << "true"; break;
- case 0x10: O << "eq_os"; break;
- case 0x11: O << "lt_oq"; break;
- case 0x12: O << "le_oq"; break;
- case 0x13: O << "unord_s"; break;
- case 0x14: O << "neq_us"; break;
- case 0x15: O << "nlt_uq"; break;
- case 0x16: O << "nle_uq"; break;
- case 0x17: O << "ord_s"; break;
- case 0x18: O << "eq_us"; break;
- case 0x19: O << "nge_uq"; break;
- case 0x1a: O << "ngt_uq"; break;
- case 0x1b: O << "false_os"; break;
- case 0x1c: O << "neq_os"; break;
- case 0x1d: O << "ge_oq"; break;
- case 0x1e: O << "gt_oq"; break;
- case 0x1f: O << "true_us"; break;
- }
-}
-
void X86AsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op,
raw_ostream &O, const char *Modifier) {
const MachineOperand &BaseReg = MI->getOperand(Op);
@@ -394,10 +354,51 @@ void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op,
printLeaMemReference(MI, Op, O, Modifier);
}
-void X86AsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op,
- raw_ostream &O) {
- O << *MF->getPICBaseSymbol() << '\n';
- O << *MF->getPICBaseSymbol() << ':';
+void X86AsmPrinter::printIntelMemReference(const MachineInstr *MI, unsigned Op,
+ raw_ostream &O, const char *Modifier,
+ unsigned AsmVariant){
+ const MachineOperand &BaseReg = MI->getOperand(Op);
+ unsigned ScaleVal = MI->getOperand(Op+1).getImm();
+ const MachineOperand &IndexReg = MI->getOperand(Op+2);
+ const MachineOperand &DispSpec = MI->getOperand(Op+3);
+ const MachineOperand &SegReg = MI->getOperand(Op+4);
+
+ // If this has a segment register, print it.
+ if (SegReg.getReg()) {
+ printOperand(MI, Op+4, O, Modifier, AsmVariant);
+ O << ':';
+ }
+
+ O << '[';
+
+ bool NeedPlus = false;
+ if (BaseReg.getReg()) {
+ printOperand(MI, Op, O, Modifier, AsmVariant);
+ NeedPlus = true;
+ }
+
+ if (IndexReg.getReg()) {
+ if (NeedPlus) O << " + ";
+ if (ScaleVal != 1)
+ O << ScaleVal << '*';
+ printOperand(MI, Op+2, O, Modifier, AsmVariant);
+ NeedPlus = true;
+ }
+
+ assert (DispSpec.isImm() && "Displacement is not an immediate!");
+ int64_t DispVal = DispSpec.getImm();
+ if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) {
+ if (NeedPlus) {
+ if (DispVal > 0)
+ O << " + ";
+ else {
+ O << " - ";
+ DispVal = -DispVal;
+ }
+ }
+ O << DispVal;
+ }
+ O << ']';
}
bool X86AsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode,
@@ -510,6 +511,11 @@ bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
unsigned OpNo, unsigned AsmVariant,
const char *ExtraCode,
raw_ostream &O) {
+ if (AsmVariant) {
+ printIntelMemReference(MI, OpNo, O);
+ return false;
+ }
+
if (ExtraCode && ExtraCode[0]) {
if (ExtraCode[1] != 0) return true; // Unknown modifier.
@@ -711,7 +717,7 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
if (!Stubs.empty()) {
OutStreamer.SwitchSection(TLOFELF.getDataRelSection());
- const TargetData *TD = TM.getTargetData();
+ const DataLayout *TD = TM.getDataLayout();
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
OutStreamer.EmitLabel(Stubs[i].first);
diff --git a/lib/Target/X86/X86AsmPrinter.h b/lib/Target/X86/X86AsmPrinter.h
index 4bae29c12a..b166a531e1 100644
--- a/lib/Target/X86/X86AsmPrinter.h
+++ b/lib/Target/X86/X86AsmPrinter.h
@@ -34,17 +34,17 @@ class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {
Subtarget = &TM.getSubtarget<X86Subtarget>();
}
- virtual const char *getPassName() const {
+ virtual const char *getPassName() const LLVM_OVERRIDE {
return "X86 AT&T-Style Assembly Printer";
}
const X86Subtarget &getSubtarget() const { return *Subtarget; }
- virtual void EmitStartOfAsmFile(Module &M);
+ virtual void EmitStartOfAsmFile(Module &M) LLVM_OVERRIDE;
- virtual void EmitEndOfAsmFile(Module &M);
+ virtual void EmitEndOfAsmFile(Module &M) LLVM_OVERRIDE;
- virtual void EmitInstruction(const MachineInstr *MI);
+ virtual void EmitInstruction(const MachineInstr *MI) LLVM_OVERRIDE;
virtual bool UseReadOnlyJumpTables() const; // @LOCALMOD
@@ -60,27 +60,28 @@ class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {
void printPCRelImm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
bool printAsmMRegister(const MachineOperand &MO, char Mode, raw_ostream &O);
- bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode,
- raw_ostream &OS);
- bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode,
- raw_ostream &OS);
-
- void printMachineInstruction(const MachineInstr *MI);
- void printSSECC(const MachineInstr *MI, unsigned Op, raw_ostream &O);
+ virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &OS) LLVM_OVERRIDE;
+ virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &OS) LLVM_OVERRIDE;
+
void printMemReference(const MachineInstr *MI, unsigned Op, raw_ostream &O,
const char *Modifier=NULL);
void printLeaMemReference(const MachineInstr *MI, unsigned Op, raw_ostream &O,
const char *Modifier=NULL);
- void printPICLabel(const MachineInstr *MI, unsigned Op, raw_ostream &O);
+ void printIntelMemReference(const MachineInstr *MI, unsigned Op,
+ raw_ostream &O, const char *Modifier=NULL,
+ unsigned AsmVariant = 1);
- bool runOnMachineFunction(MachineFunction &F);
+ virtual bool runOnMachineFunction(MachineFunction &F) LLVM_OVERRIDE;
void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
- MachineLocation getDebugValueLocation(const MachineInstr *MI) const;
+ virtual MachineLocation
+ getDebugValueLocation(const MachineInstr *MI) const LLVM_OVERRIDE;
};
} // end namespace llvm
diff --git a/lib/Target/X86/X86COFFMachineModuleInfo.h b/lib/Target/X86/X86COFFMachineModuleInfo.h
index 471eb31131..a5a8dc18e4 100644
--- a/lib/Target/X86/X86COFFMachineModuleInfo.h
+++ b/lib/Target/X86/X86COFFMachineModuleInfo.h
@@ -20,7 +20,7 @@
namespace llvm {
class X86MachineFunctionInfo;
- class TargetData;
+ class DataLayout;
/// X86COFFMachineModuleInfo - This is a MachineModuleInfoImpl implementation
/// for X86 COFF targets.
diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp
index f89e399658..ee6408b403 100644
--- a/lib/Target/X86/X86CodeEmitter.cpp
+++ b/lib/Target/X86/X86CodeEmitter.cpp
@@ -43,7 +43,7 @@ namespace {
template<class CodeEmitter>
class Emitter : public MachineFunctionPass {
const X86InstrInfo *II;
- const TargetData *TD;
+ const DataLayout *TD;
X86TargetMachine &TM;
CodeEmitter &MCE;
MachineModuleInfo *MMI;
@@ -57,7 +57,7 @@ namespace {
MCE(mce), PICBaseOffset(0), Is64BitMode(false),
IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
Emitter(X86TargetMachine &tm, CodeEmitter &mce,
- const X86InstrInfo &ii, const TargetData &td, bool is64)
+ const X86InstrInfo &ii, const DataLayout &td, bool is64)
: MachineFunctionPass(ID), II(&ii), TD(&td), TM(tm),
MCE(mce), PICBaseOffset(0), Is64BitMode(is64),
IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
@@ -110,6 +110,14 @@ namespace {
void emitMemModRMByte(const MachineInstr &MI,
unsigned Op, unsigned RegOpcodeField,
intptr_t PCAdj = 0);
+
+ unsigned getX86RegNum(unsigned RegNo) const {
+ const TargetRegisterInfo *TRI = TM.getRegisterInfo();
+ return TRI->getEncodingValue(RegNo) & 0x7;
+ }
+
+ unsigned char getVEXRegisterEncoding(const MachineInstr &MI,
+ unsigned OpNum) const;
};
template<class CodeEmitter>
@@ -129,7 +137,7 @@ bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
MCE.setModuleInfo(MMI);
II = TM.getInstrInfo();
- TD = TM.getTargetData();
+ TD = TM.getDataLayout();
Is64BitMode = TM.getSubtarget<X86Subtarget>().is64Bit();
IsPIC = TM.getRelocationModel() == Reloc::PIC_;
@@ -364,7 +372,7 @@ inline static unsigned char ModRMByte(unsigned Mod, unsigned RegOpcode,
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitRegModRMByte(unsigned ModRMReg,
unsigned RegOpcodeFld){
- MCE.emitByte(ModRMByte(3, RegOpcodeFld, X86_MC::getX86RegNum(ModRMReg)));
+ MCE.emitByte(ModRMByte(3, RegOpcodeFld, getX86RegNum(ModRMReg)));
}
template<class CodeEmitter>
@@ -502,7 +510,7 @@ void Emitter<CodeEmitter>::emitMemModRMByte(const MachineInstr &MI,
// 2-7) and absolute references.
unsigned BaseRegNo = -1U;
if (BaseReg != 0 && BaseReg != X86::RIP)
- BaseRegNo = X86_MC::getX86RegNum(BaseReg);
+ BaseRegNo = getX86RegNum(BaseReg);
if (// The SIB byte must be used if there is an index register.
IndexReg.getReg() == 0 &&
@@ -578,15 +586,15 @@ void Emitter<CodeEmitter>::emitMemModRMByte(const MachineInstr &MI,
// Manual 2A, table 2-7. The displacement has already been output.
unsigned IndexRegNo;
if (IndexReg.getReg())
- IndexRegNo = X86_MC::getX86RegNum(IndexReg.getReg());
+ IndexRegNo = getX86RegNum(IndexReg.getReg());
else // Examples: [ESP+1*<noreg>+4] or [scaled idx]+disp32 (MOD=0,BASE=5)
IndexRegNo = 4;
emitSIBByte(SS, IndexRegNo, 5);
} else {
- unsigned BaseRegNo = X86_MC::getX86RegNum(BaseReg);
+ unsigned BaseRegNo = getX86RegNum(BaseReg);
unsigned IndexRegNo;
if (IndexReg.getReg())
- IndexRegNo = X86_MC::getX86RegNum(IndexReg.getReg());
+ IndexRegNo = getX86RegNum(IndexReg.getReg());
else
IndexRegNo = 4; // For example [ESP+1*<noreg>+4]
emitSIBByte(SS, IndexRegNo, BaseRegNo);
@@ -757,10 +765,12 @@ void Emitter<CodeEmitter>::emitOpcodePrefix(uint64_t TSFlags,
// VEX.VVVV => XMM9 => ~9
//
// See table 4-35 of Intel AVX Programming Reference for details.
-static unsigned char getVEXRegisterEncoding(const MachineInstr &MI,
- unsigned OpNum) {
+template<class CodeEmitter>
+unsigned char
+Emitter<CodeEmitter>::getVEXRegisterEncoding(const MachineInstr &MI,
+ unsigned OpNum) const {
unsigned SrcReg = MI.getOperand(OpNum).getReg();
- unsigned SrcRegNum = X86_MC::getX86RegNum(MI.getOperand(OpNum).getReg());
+ unsigned SrcRegNum = getX86RegNum(MI.getOperand(OpNum).getReg());
if (X86II::isX86_64ExtendedReg(SrcReg))
SrcRegNum |= 8;
@@ -1258,7 +1268,7 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
case X86II::AddRegFrm: {
MCE.emitByte(BaseOpcode +
- X86_MC::getX86RegNum(MI.getOperand(CurOp++).getReg()));
+ getX86RegNum(MI.getOperand(CurOp++).getReg()));
if (CurOp == NumOps)
break;
@@ -1293,7 +1303,7 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
case X86II::MRMDestReg: {
MCE.emitByte(BaseOpcode);
emitRegModRMByte(MI.getOperand(CurOp).getReg(),
- X86_MC::getX86RegNum(MI.getOperand(CurOp+1).getReg()));
+ getX86RegNum(MI.getOperand(CurOp+1).getReg()));
CurOp += 2;
break;
}
@@ -1304,7 +1314,7 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV)
SrcRegNum++;
emitMemModRMByte(MI, CurOp,
- X86_MC::getX86RegNum(MI.getOperand(SrcRegNum).getReg()));
+ getX86RegNum(MI.getOperand(SrcRegNum).getReg()));
CurOp = SrcRegNum + 1;
break;
}
@@ -1320,7 +1330,7 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
++SrcRegNum;
emitRegModRMByte(MI.getOperand(SrcRegNum).getReg(),
- X86_MC::getX86RegNum(MI.getOperand(CurOp).getReg()));
+ getX86RegNum(MI.getOperand(CurOp).getReg()));
// 2 operands skipped with HasMemOp4, compensate accordingly
CurOp = HasMemOp4 ? SrcRegNum : SrcRegNum + 1;
if (HasVEX_4VOp3)
@@ -1342,7 +1352,7 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
intptr_t PCAdj = (CurOp + AddrOperands + 1 != NumOps) ?
X86II::getSizeOfImm(Desc->TSFlags) : 0;
emitMemModRMByte(MI, FirstMemOp,
- X86_MC::getX86RegNum(MI.getOperand(CurOp).getReg()),PCAdj);
+ getX86RegNum(MI.getOperand(CurOp).getReg()),PCAdj);
CurOp += AddrOperands + 1;
if (HasVEX_4VOp3)
++CurOp;
@@ -1432,7 +1442,7 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
MCE.emitByte(BaseOpcode);
// Duplicate register, used by things like MOV8r0 (aka xor reg,reg).
emitRegModRMByte(MI.getOperand(CurOp).getReg(),
- X86_MC::getX86RegNum(MI.getOperand(CurOp).getReg()));
+ getX86RegNum(MI.getOperand(CurOp).getReg()));
++CurOp;
break;
@@ -1465,7 +1475,7 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
const MachineOperand &MO = MI.getOperand(HasMemOp4 ? MemOp4_I8IMMOperand
: CurOp);
++CurOp;
- unsigned RegNum = X86_MC::getX86RegNum(MO.getReg()) << 4;
+ unsigned RegNum = getX86RegNum(MO.getReg()) << 4;
if (X86II::isX86_64ExtendedReg(MO.getReg()))
RegNum |= 1 << 7;
// If there is an additional 5th operand it must be an immediate, which
diff --git a/lib/Target/X86/X86ELFWriterInfo.cpp b/lib/Target/X86/X86ELFWriterInfo.cpp
index c1a49a7646..2e08ef811f 100644
--- a/lib/Target/X86/X86ELFWriterInfo.cpp
+++ b/lib/Target/X86/X86ELFWriterInfo.cpp
@@ -16,7 +16,7 @@
#include "llvm/Function.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index 23450f761c..c9301bb2c9 100644
--- a/lib/Target/X86/X86FastISel.cpp
+++ b/lib/Target/X86/X86FastISel.cpp
@@ -724,6 +724,8 @@ bool X86FastISel::X86SelectStore(const Instruction *I) {
bool X86FastISel::X86SelectRet(const Instruction *I) {
const ReturnInst *Ret = cast<ReturnInst>(I);
const Function &F = *I->getParent()->getParent();
+ const X86MachineFunctionInfo *X86MFInfo =
+ FuncInfo.MF->getInfo<X86MachineFunctionInfo>();
if (!FuncInfo.CanLowerReturn)
return false;
@@ -738,8 +740,7 @@ bool X86FastISel::X86SelectRet(const Instruction *I) {
return false;
// Don't handle popping bytes on return for now.
- if (FuncInfo.MF->getInfo<X86MachineFunctionInfo>()
- ->getBytesToPopOnReturn() != 0)
+ if (X86MFInfo->getBytesToPopOnReturn() != 0)
return 0;
// fastcc with -tailcallopt is intended to provide a guaranteed
@@ -823,6 +824,19 @@ bool X86FastISel::X86SelectRet(const Instruction *I) {
MRI.addLiveOut(VA.getLocReg());
}
+ // The x86-64 ABI for returning structs by value requires that we copy
+ // the sret argument into %rax for the return. We saved the argument into
+ // a virtual register in the entry block, so now we copy the value out
+ // and into %rax.
+ if (Subtarget->is64Bit() && F.hasStructRetAttr()) {
+ unsigned Reg = X86MFInfo->getSRetReturnReg();
+ assert(Reg &&
+ "SRetReturnReg should have been set in LowerFormalArguments()!");
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
+ X86::RAX).addReg(Reg);
+ MRI.addLiveOut(X86::RAX);
+ }
+
// Now emit the RET.
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::RET));
return true;
@@ -1541,9 +1555,9 @@ static unsigned computeBytesPoppedByCallee(const X86Subtarget &Subtarget,
CallingConv::ID CC = CS.getCallingConv();
if (CC == CallingConv::Fast || CC == CallingConv::GHC)
return 0;
- if (!CS.paramHasAttr(1, Attribute::StructRet))
+ if (!CS.paramHasAttr(1, Attributes::StructRet))
return 0;
- if (CS.paramHasAttr(1, Attribute::InReg))
+ if (CS.paramHasAttr(1, Attributes::InReg))
return 0;
return 4;
}
@@ -1622,12 +1636,12 @@ bool X86FastISel::DoSelectCall(const Instruction *I, const char *MemIntName) {
Value *ArgVal = *i;
ISD::ArgFlagsTy Flags;
unsigned AttrInd = i - CS.arg_begin() + 1;
- if (CS.paramHasAttr(AttrInd, Attribute::SExt))
+ if (CS.paramHasAttr(AttrInd, Attributes::SExt))
Flags.setSExt();
- if (CS.paramHasAttr(AttrInd, Attribute::ZExt))
+ if (CS.paramHasAttr(AttrInd, Attributes::ZExt))
Flags.setZExt();
- if (CS.paramHasAttr(AttrInd, Attribute::ByVal)) {
+ if (CS.paramHasAttr(AttrInd, Attributes::ByVal)) {
PointerType *Ty = cast<PointerType>(ArgVal->getType());
Type *ElementTy = Ty->getElementType();
unsigned FrameSize = TD.getTypeAllocSize(ElementTy);
@@ -1641,9 +1655,9 @@ bool X86FastISel::DoSelectCall(const Instruction *I, const char *MemIntName) {
return false;
}
- if (CS.paramHasAttr(AttrInd, Attribute::InReg))
+ if (CS.paramHasAttr(AttrInd, Attributes::InReg))
Flags.setInReg();
- if (CS.paramHasAttr(AttrInd, Attribute::Nest))
+ if (CS.paramHasAttr(AttrInd, Attributes::Nest))
Flags.setNest();
// If this is an i1/i8/i16 argument, promote to i32 to avoid an extra
@@ -1933,11 +1947,11 @@ bool X86FastISel::DoSelectCall(const Instruction *I, const char *MemIntName) {
ISD::InputArg MyFlags;
MyFlags.VT = RegisterVT.getSimpleVT();
MyFlags.Used = !CS.getInstruction()->use_empty();
- if (CS.paramHasAttr(0, Attribute::SExt))
+ if (CS.paramHasAttr(0, Attributes::SExt))
MyFlags.Flags.setSExt();
- if (CS.paramHasAttr(0, Attribute::ZExt))
+ if (CS.paramHasAttr(0, Attributes::ZExt))
MyFlags.Flags.setZExt();
- if (CS.paramHasAttr(0, Attribute::InReg))
+ if (CS.paramHasAttr(0, Attributes::InReg))
MyFlags.Flags.setInReg();
Ins.push_back(MyFlags);
}
diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp
index 85922f1277..4141068806 100644
--- a/lib/Target/X86/X86FrameLowering.cpp
+++ b/lib/Target/X86/X86FrameLowering.cpp
@@ -25,7 +25,7 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/ADT/SmallSet.h"
@@ -315,7 +315,7 @@ void X86FrameLowering::emitCalleeSavedFrameMoves(MachineFunction &MF,
if (CSI.empty()) return;
std::vector<MachineMove> &Moves = MMI.getFrameMoves();
- const TargetData *TD = TM.getTargetData();
+ const DataLayout *TD = TM.getDataLayout();
bool HasFP = hasFP(MF);
// Calculate amount of bytes used for return address storing.
@@ -676,7 +676,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF) const {
// function, and use up to 128 bytes of stack space, don't have a frame
// pointer, calls, or dynamic alloca then we do not need to adjust the
// stack pointer (we fit in the Red Zone).
- if (Is64Bit && !Fn->getFnAttributes().hasNoRedZoneAttr() &&
+ if (Is64Bit && !Fn->getFnAttributes().hasAttribute(Attributes::NoRedZone) &&
!RegInfo->needsStackRealignment(MF) &&
!MFI->hasVarSizedObjects() && // No dynamic alloca.
!MFI->adjustsStack() && // No calls.
@@ -717,7 +717,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF) const {
// ELSE => DW_CFA_offset_extended
std::vector<MachineMove> &Moves = MMI.getFrameMoves();
- const TargetData *TD = MF.getTarget().getTargetData();
+ const DataLayout *TD = MF.getTarget().getDataLayout();
uint64_t NumBytes = 0;
int stackGrowth = -TM.getFrameLowering()->getStackSlotSize(); // @LOCALMOD
@@ -838,8 +838,6 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF) const {
MI->getOperand(3).setIsDead();
}
- DL = MBB.findDebugLoc(MBBI);
-
// If there is an SUB32ri of ESP immediately before this instruction, merge
// the two. This can be the case when tail call elimination is enabled and
// the callee has more arguments then the caller.
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index 767e261a82..396bac42c3 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -377,7 +377,7 @@ X86DAGToDAGISel::IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const {
/// MoveBelowCallOrigChain - Replace the original chain operand of the call with
/// load's chain operand and move load below the call's chain operand.
static void MoveBelowOrigChain(SelectionDAG *CurDAG, SDValue Load,
- SDValue Call, SDValue OrigChain) {
+ SDValue Call, SDValue OrigChain) {
SmallVector<SDValue, 8> Ops;
SDValue Chain = OrigChain.getOperand(0);
if (Chain.getNode() == Load.getNode())
@@ -401,11 +401,13 @@ static void MoveBelowOrigChain(SelectionDAG *CurDAG, SDValue Load,
CurDAG->UpdateNodeOperands(OrigChain.getNode(), &Ops[0], Ops.size());
CurDAG->UpdateNodeOperands(Load.getNode(), Call.getOperand(0),
Load.getOperand(1), Load.getOperand(2));
+
+ unsigned NumOps = Call.getNode()->getNumOperands();
Ops.clear();
Ops.push_back(SDValue(Load.getNode(), 1));
- for (unsigned i = 1, e = Call.getNode()->getNumOperands(); i != e; ++i)
+ for (unsigned i = 1, e = NumOps; i != e; ++i)
Ops.push_back(Call.getOperand(i));
- CurDAG->UpdateNodeOperands(Call.getNode(), &Ops[0], Ops.size());
+ CurDAG->UpdateNodeOperands(Call.getNode(), &Ops[0], NumOps);
}
/// isCalleeLoad - Return true if call address is a load and it can be
@@ -414,6 +416,10 @@ static void MoveBelowOrigChain(SelectionDAG *CurDAG, SDValue Load,
/// In the case of a tail call, there isn't a callseq node between the call
/// chain and the load.
static bool isCalleeLoad(SDValue Callee, SDValue &Chain, bool HasCallSeq) {
+ // The transformation is somewhat dangerous if the call's chain was glued to
+ // the call. After MoveBelowOrigChain the load is moved between the call and
+ // the chain, this can create a cycle if the load is not folded. So it is
+ // *really* important that we are sure the load will be folded.
if (Callee.getNode() == Chain.getNode() || !Callee.hasOneUse())
return false;
LoadSDNode *LD = dyn_cast<LoadSDNode>(Callee.getNode());
@@ -443,7 +449,8 @@ static bool isCalleeLoad(SDValue Callee, SDValue &Chain, bool HasCallSeq) {
void X86DAGToDAGISel::PreprocessISelDAG() {
// OptForSize is used in pattern predicates that isel is matching.
- OptForSize = MF->getFunction()->getFnAttributes().hasOptimizeForSizeAttr();
+ OptForSize = MF->getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize);
for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
E = CurDAG->allnodes_end(); I != E; ) {
@@ -452,7 +459,10 @@ void X86DAGToDAGISel::PreprocessISelDAG() {
if (OptLevel != CodeGenOpt::None &&
!Subtarget->isTargetNaCl() && // @LOCALMOD: We can't fold load/call
(N->getOpcode() == X86ISD::CALL ||
- N->getOpcode() == X86ISD::TC_RETURN)) {
+ (N->getOpcode() == X86ISD::TC_RETURN &&
+ // Only does this if load can be foled into TC_RETURN.
+ (Subtarget->is64Bit() ||
+ getTargetMachine().getRelocationModel() != Reloc::PIC_)))) {
/// Also try moving call address load from outside callseq_start to just
/// before the call to allow it to be folded.
///
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index bdee1e682d..391937c265 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -169,7 +169,7 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
// @LOCALMOD-END
RegInfo = TM.getRegisterInfo();
- TD = getTargetData();
+ TD = getDataLayout();
// Set up the TargetLowering object.
static const MVT IntVTs[] = { MVT::i8, MVT::i16, MVT::i32, MVT::i64 };
@@ -192,7 +192,7 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
// Bypass i32 with i8 on Atom when compiling with O2
if (Subtarget->hasSlowDivide() && TM.getOptLevel() >= CodeGenOpt::Default)
- addBypassSlowDivType(Type::getInt32Ty(getGlobalContext()), Type::getInt8Ty(getGlobalContext()));
+ addBypassSlowDiv(32, 8);
if (Subtarget->isTargetWindows() && !Subtarget->isTargetCygMing()) {
// Setup Windows compiler runtime calls.
@@ -1361,7 +1361,7 @@ X86TargetLowering::getOptimalMemOpType(uint64_t Size,
// cases like PR2962. This should be removed when PR2962 is fixed.
const Function *F = MF.getFunction();
if (IsZeroVal &&
- !F->getFnAttributes().hasNoImplicitFloatAttr()) {
+ !F->getFnAttributes().hasAttribute(Attributes::NoImplicitFloat)) {
if (Size >= 16 &&
(Subtarget->isUnalignedMemAccessFast() ||
((DstAlign == 0 || DstAlign >= 16) &&
@@ -2040,7 +2040,8 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
unsigned NumIntRegs = CCInfo.getFirstUnallocated(GPR64ArgRegs,
TotalNumIntRegs);
- bool NoImplicitFloatOps = Fn->getFnAttributes().hasNoImplicitFloatAttr();
+ bool NoImplicitFloatOps = Fn->getFnAttributes().
+ hasAttribute(Attributes::NoImplicitFloat);
assert(!(NumXMMRegs && !Subtarget->hasSSE1()) &&
"SSE register cannot be used when SSE is disabled!");
assert(!(NumXMMRegs && MF.getTarget().Options.UseSoftFloat &&
@@ -2516,7 +2517,8 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
OpFlags = X86II::MO_DARWIN_STUB;
} else if (Subtarget->isPICStyleRIPRel() &&
isa<Function>(GV) &&
- cast<Function>(GV)->getFnAttributes().hasNonLazyBindAttr()) {
+ cast<Function>(GV)->getFnAttributes().
+ hasAttribute(Attributes::NonLazyBind)) {
// If the function is marked as non-lazy, generate an indirect call
// which loads from the GOT directly. This avoids runtime overhead
// at the cost of eager binding (and one extra byte of encoding).
@@ -3573,7 +3575,7 @@ SDValue Compact8x32ShuffleNode(ShuffleVectorSDNode *SVOp,
if (!MatchEvenMask && !MatchOddMask)
return SDValue();
-
+
SDValue UndefNode = DAG.getNode(ISD::UNDEF, dl, VT);
SDValue Op0 = SVOp->getOperand(0);
@@ -6085,7 +6087,7 @@ SDValue LowerVECTOR_SHUFFLEv32i8(ShuffleVectorSDNode *SVOp,
bool V1IsAllZero = ISD::isBuildVectorAllZeros(V1.getNode());
bool V2IsAllZero = ISD::isBuildVectorAllZeros(V2.getNode());
- // VPSHUFB may be generated if
+ // VPSHUFB may be generated if
// (1) one of input vector is undefined or zeroinitializer.
// The mask value 0x80 puts 0 in the corresponding slot of the vector.
// And (2) the mask indexes don't cross the 128-bit lane.
@@ -6661,7 +6663,8 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const {
bool HasAVX = Subtarget->hasAVX();
bool HasAVX2 = Subtarget->hasAVX2();
MachineFunction &MF = DAG.getMachineFunction();
- bool OptForSize = MF.getFunction()->getFnAttributes().hasOptimizeForSizeAttr();
+ bool OptForSize = MF.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize);
assert(VT.getSizeInBits() != 64 && "Can't lower MMX shuffles");
@@ -9763,7 +9766,7 @@ SDValue X86TargetLowering::LowerVAARG(SDValue Op, SelectionDAG &DAG) const {
EVT ArgVT = Op.getNode()->getValueType(0);
Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
- uint32_t ArgSize = getTargetData()->getTypeAllocSize(ArgTy);
+ uint32_t ArgSize = getDataLayout()->getTypeAllocSize(ArgTy);
uint8_t ArgMode;
// Decide which area this value should be read from.
@@ -9783,7 +9786,8 @@ SDValue X86TargetLowering::LowerVAARG(SDValue Op, SelectionDAG &DAG) const {
// Sanity Check: Make sure using fp_offset makes sense.
assert(!getTargetMachine().Options.UseSoftFloat &&
!(DAG.getMachineFunction()
- .getFunction()->getFnAttributes().hasNoImplicitFloatAttr()) &&
+ .getFunction()->getFnAttributes()
+ .hasAttribute(Attributes::NoImplicitFloat)) &&
Subtarget->hasSSE1());
}
@@ -10579,6 +10583,7 @@ SDValue X86TargetLowering::LowerINIT_TRAMPOLINE(SDValue Op,
DebugLoc dl = Op.getDebugLoc();
const Value *TrmpAddr = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
+ const TargetRegisterInfo* TRI = getTargetMachine().getRegisterInfo();
if (Subtarget->is64Bit()) {
SDValue OutChains[6];
@@ -10587,8 +10592,8 @@ SDValue X86TargetLowering::LowerINIT_TRAMPOLINE(SDValue Op,
const unsigned char JMP64r = 0xFF; // 64-bit jmp through register opcode.
const unsigned char MOV64ri = 0xB8; // X86::MOV64ri opcode.
- const unsigned char N86R10 = X86_MC::getX86RegNum(X86::R10);
- const unsigned char N86R11 = X86_MC::getX86RegNum(X86::R11);
+ const unsigned char N86R10 = TRI->getEncodingValue(X86::R10) & 0x7;
+ const unsigned char N86R11 = TRI->getEncodingValue(X86::R11) & 0x7;
const unsigned char REX_WB = 0x40 | 0x08 | 0x01; // REX prefix
@@ -10661,7 +10666,7 @@ SDValue X86TargetLowering::LowerINIT_TRAMPOLINE(SDValue Op,
for (FunctionType::param_iterator I = FTy->param_begin(),
E = FTy->param_end(); I != E; ++I, ++Idx)
- if (Attrs.paramHasAttr(Idx, Attribute::InReg))
+ if (Attrs.getParamAttributes(Idx).hasAttribute(Attributes::InReg))
// FIXME: should only count parameters that are lowered to integers.
InRegCount += (TD->getTypeSizeInBits(*I) + 31) / 32;
@@ -10690,7 +10695,7 @@ SDValue X86TargetLowering::LowerINIT_TRAMPOLINE(SDValue Op,
// This is storing the opcode for MOV32ri.
const unsigned char MOV32ri = 0xB8; // X86::MOV32ri's opcode byte.
- const unsigned char N86Reg = X86_MC::getX86RegNum(NestReg);
+ const unsigned char N86Reg = TRI->getEncodingValue(NestReg) & 0x7;
OutChains[0] = DAG.getStore(Root, dl,
DAG.getConstant(MOV32ri|N86Reg, MVT::i8),
Trmp, MachinePointerInfo(TrmpAddr),
@@ -12284,7 +12289,7 @@ X86TargetLowering::EmitAtomicLoadArith(MachineInstr *MI,
SrcReg = MI->getOperand(CurOp++).getReg();
const TargetRegisterClass *RC = MRI.getRegClass(DstReg);
- EVT VT = *RC->vt_begin();
+ MVT::SimpleValueType VT = *RC->vt_begin();
unsigned AccPhyReg = getX86SubSuperRegister(X86::EAX, VT);
unsigned LCMPXCHGOpc = getCmpXChgOpcode(VT);
@@ -14102,7 +14107,7 @@ static SDValue XFormVExtractWithShuffleIntoLoad(SDNode *N, SelectionDAG &DAG,
// alignment is valid.
unsigned Align = LN0->getAlignment();
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
- unsigned NewAlign = TLI.getTargetData()->
+ unsigned NewAlign = TLI.getDataLayout()->
getABITypeAlignment(VT.getTypeForEVT(*DAG.getContext()));
if (NewAlign > Align || !TLI.isOperationLegalOrCustom(ISD::LOAD, VT))
@@ -15636,7 +15641,8 @@ static SDValue PerformSTORECombine(SDNode *N, SelectionDAG &DAG,
return SDValue();
const Function *F = DAG.getMachineFunction().getFunction();
- bool NoImplicitFloatOps = F->getFnAttributes().hasNoImplicitFloatAttr();
+ bool NoImplicitFloatOps = F->getFnAttributes().
+ hasAttribute(Attributes::NoImplicitFloat);
bool F64IsLegal = !DAG.getTarget().Options.UseSoftFloat && !NoImplicitFloatOps
&& Subtarget->hasSSE2();
if ((VT.isVector() ||
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index a53909b7a0..1022c29fec 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -709,7 +709,7 @@ namespace llvm {
/// make the right decision when generating code for different targets.
const X86Subtarget *Subtarget;
const X86RegisterInfo *RegInfo;
- const TargetData *TD;
+ const DataLayout *TD;
/// X86StackPtr - X86 physical register used as stack ptr.
unsigned X86StackPtr;
diff --git a/lib/Target/X86/X86InstrCompiler.td b/lib/Target/X86/X86InstrCompiler.td
index 3a1ac11f9c..ea705d6e11 100644
--- a/lib/Target/X86/X86InstrCompiler.td
+++ b/lib/Target/X86/X86InstrCompiler.td
@@ -230,25 +230,18 @@ def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64i32imm:$src),
IIC_ALU_NONMEM>;
// Use sbb to materialize carry bit.
-let Uses = [EFLAGS], Defs = [EFLAGS], isCodeGenOnly = 1 in {
+let Uses = [EFLAGS], Defs = [EFLAGS], isPseudo = 1 in {
// FIXME: These are pseudo ops that should be replaced with Pat<> patterns.
// However, Pat<> can't replicate the destination reg into the inputs of the
// result.
-// FIXME: Change these to have encoding Pseudo when X86MCCodeEmitter replaces
-// X86CodeEmitter.
-def SETB_C8r : I<0x18, MRMInitReg, (outs GR8:$dst), (ins), "",
- [(set GR8:$dst, (X86setcc_c X86_COND_B, EFLAGS))],
- IIC_ALU_NONMEM>;
-def SETB_C16r : I<0x19, MRMInitReg, (outs GR16:$dst), (ins), "",
- [(set GR16:$dst, (X86setcc_c X86_COND_B, EFLAGS))],
- IIC_ALU_NONMEM>,
- OpSize;
-def SETB_C32r : I<0x19, MRMInitReg, (outs GR32:$dst), (ins), "",
- [(set GR32:$dst, (X86setcc_c X86_COND_B, EFLAGS))],
- IIC_ALU_NONMEM>;
-def SETB_C64r : RI<0x19, MRMInitReg, (outs GR64:$dst), (ins), "",
- [(set GR64:$dst, (X86setcc_c X86_COND_B, EFLAGS))],
- IIC_ALU_NONMEM>;
+def SETB_C8r : I<0, Pseudo, (outs GR8:$dst), (ins), "",
+ [(set GR8:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>;
+def SETB_C16r : I<0, Pseudo, (outs GR16:$dst), (ins), "",
+ [(set GR16:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>;
+def SETB_C32r : I<0, Pseudo, (outs GR32:$dst), (ins), "",
+ [(set GR32:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>;
+def SETB_C64r : I<0, Pseudo, (outs GR64:$dst), (ins), "",
+ [(set GR64:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>;
} // isCodeGenOnly
@@ -453,6 +446,11 @@ def CMOV_GR16 : I<0, Pseudo,
"#CMOV_GR16* PSEUDO!",
[(set GR16:$dst,
(X86cmov GR16:$src1, GR16:$src2, imm:$cond, EFLAGS))]>;
+} // Predicates = [NoCMov]
+
+// fcmov doesn't handle all possible EFLAGS, provide a fallback if there is no
+// SSE1.
+let Predicates = [FPStackf32] in
def CMOV_RFP32 : I<0, Pseudo,
(outs RFP32:$dst),
(ins RFP32:$src1, RFP32:$src2, i8imm:$cond),
@@ -460,6 +458,9 @@ def CMOV_RFP32 : I<0, Pseudo,
[(set RFP32:$dst,
(X86cmov RFP32:$src1, RFP32:$src2, imm:$cond,
EFLAGS))]>;
+// fcmov doesn't handle all possible EFLAGS, provide a fallback if there is no
+// SSE2.
+let Predicates = [FPStackf64] in
def CMOV_RFP64 : I<0, Pseudo,
(outs RFP64:$dst),
(ins RFP64:$src1, RFP64:$src2, i8imm:$cond),
@@ -474,7 +475,6 @@ def CMOV_RFP80 : I<0, Pseudo,
[(set RFP80:$dst,
(X86cmov RFP80:$src1, RFP80:$src2, imm:$cond,
EFLAGS))]>;
-} // Predicates = [NoCMov]
} // UsesCustomInserter = 1, Uses = [EFLAGS]
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
index af570adb79..5628c3eada 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -3515,6 +3515,14 @@ static bool Expand2AddrUndef(MachineInstr *MI, const MCInstrDesc &Desc) {
bool X86InstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
bool HasAVX = TM.getSubtarget<X86Subtarget>().hasAVX();
switch (MI->getOpcode()) {
+ case X86::SETB_C8r:
+ return Expand2AddrUndef(MI, get(X86::SBB8rr));
+ case X86::SETB_C16r:
+ return Expand2AddrUndef(MI, get(X86::SBB16rr));
+ case X86::SETB_C32r:
+ return Expand2AddrUndef(MI, get(X86::SBB32rr));
+ case X86::SETB_C64r:
+ return Expand2AddrUndef(MI, get(X86::SBB64rr));
case X86::V_SET0:
case X86::FsFLD0SS:
case X86::FsFLD0SD:
@@ -3826,7 +3834,8 @@ MachineInstr* X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
// Unless optimizing for size, don't fold to avoid partial
// register update stalls
- if (!MF.getFunction()->getFnAttributes().hasOptimizeForSizeAttr() &&
+ if (!MF.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize) &&
hasPartialRegUpdate(MI->getOpcode()))
return 0;
@@ -3867,7 +3876,8 @@ MachineInstr* X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
// Unless optimizing for size, don't fold to avoid partial
// register update stalls
- if (!MF.getFunction()->getFnAttributes().hasOptimizeForSizeAttr() &&
+ if (!MF.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize) &&
hasPartialRegUpdate(MI->getOpcode()))
return 0;
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 5074724fb8..4094cb619f 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -426,7 +426,7 @@ def SSECC : Operand<i8> {
}
def AVXCC : Operand<i8> {
- let PrintMethod = "printSSECC";
+ let PrintMethod = "printAVXCC";
let OperandType = "OPERAND_IMMEDIATE";
}
diff --git a/lib/Target/X86/X86MCInstLower.cpp b/lib/Target/X86/X86MCInstLower.cpp
index 811a4b5618..d24ff73307 100644
--- a/lib/Target/X86/X86MCInstLower.cpp
+++ b/lib/Target/X86/X86MCInstLower.cpp
@@ -371,10 +371,6 @@ ReSimplify:
case X86::MOVZX64rm8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rm8); break;
case X86::MOVZX64rr16: LowerSubReg32_Op0(OutMI, X86::MOVZX32rr16); break;
case X86::MOVZX64rm16: LowerSubReg32_Op0(OutMI, X86::MOVZX32rm16); break;
- case X86::SETB_C8r: LowerUnaryToTwoAddr(OutMI, X86::SBB8rr); break;
- case X86::SETB_C16r: LowerUnaryToTwoAddr(OutMI, X86::SBB16rr); break;
- case X86::SETB_C32r: LowerUnaryToTwoAddr(OutMI, X86::SBB32rr); break;
- case X86::SETB_C64r: LowerUnaryToTwoAddr(OutMI, X86::SBB64rr); break;
case X86::MOV8r0: LowerUnaryToTwoAddr(OutMI, X86::XOR8rr); break;
case X86::MOV32r0: LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); break;
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
index 18101ad6b1..4f495c2386 100644
--- a/lib/Target/X86/X86RegisterInfo.cpp
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -111,23 +111,7 @@ X86RegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const {
int
X86RegisterInfo::getSEHRegNum(unsigned i) const {
- int reg = X86_MC::getX86RegNum(i);
- switch (i) {
- case X86::R8: case X86::R8D: case X86::R8W: case X86::R8B:
- case X86::R9: case X86::R9D: case X86::R9W: case X86::R9B:
- case X86::R10: case X86::R10D: case X86::R10W: case X86::R10B:
- case X86::R11: case X86::R11D: case X86::R11W: case X86::R11B:
- case X86::R12: case X86::R12D: case X86::R12W: case X86::R12B:
- case X86::R13: case X86::R13D: case X86::R13W: case X86::R13B:
- case X86::R14: case X86::R14D: case X86::R14W: case X86::R14B:
- case X86::R15: case X86::R15D: case X86::R15W: case X86::R15B:
- case X86::XMM8: case X86::XMM9: case X86::XMM10: case X86::XMM11:
- case X86::XMM12: case X86::XMM13: case X86::XMM14: case X86::XMM15:
- case X86::YMM8: case X86::YMM9: case X86::YMM10: case X86::YMM11:
- case X86::YMM12: case X86::YMM13: case X86::YMM14: case X86::YMM15:
- reg += 8;
- }
- return reg;
+ return getEncodingValue(i);
}
const TargetRegisterClass *
@@ -422,8 +406,9 @@ bool X86RegisterInfo::needsStackRealignment(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
const Function *F = MF.getFunction();
unsigned StackAlign = TM.getFrameLowering()->getStackAlignment();
- bool requiresRealignment = ((MFI->getMaxAlignment() > StackAlign) ||
- F->getFnAttributes().hasStackAlignmentAttr());
+ bool requiresRealignment =
+ ((MFI->getMaxAlignment() > StackAlign) ||
+ F->getFnAttributes().hasAttribute(Attributes::StackAlignment));
// If we've requested that we force align the stack do so now.
if (ForceStackAlign)
@@ -614,9 +599,10 @@ unsigned X86RegisterInfo::getEHHandlerRegister() const {
}
namespace llvm {
-unsigned getX86SubSuperRegister(unsigned Reg, EVT VT, bool High) {
- switch (VT.getSimpleVT().SimpleTy) {
- default: return Reg;
+unsigned getX86SubSuperRegister(unsigned Reg, MVT::SimpleValueType VT,
+ bool High) {
+ switch (VT) {
+ default: llvm_unreachable("Unexpected VT");
case MVT::i8:
if (High) {
switch (Reg) {
@@ -632,7 +618,7 @@ unsigned getX86SubSuperRegister(unsigned Reg, EVT VT, bool High) {
}
} else {
switch (Reg) {
- default: return 0;
+ default: llvm_unreachable("Unexpected register");
case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
return X86::AL;
case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
@@ -669,7 +655,7 @@ unsigned getX86SubSuperRegister(unsigned Reg, EVT VT, bool High) {
}
case MVT::i16:
switch (Reg) {
- default: return Reg;
+ default: llvm_unreachable("Unexpected register");
case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
return X86::AX;
case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
@@ -705,7 +691,7 @@ unsigned getX86SubSuperRegister(unsigned Reg, EVT VT, bool High) {
}
case MVT::i32:
switch (Reg) {
- default: return Reg;
+ default: llvm_unreachable("Unexpected register");
case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
return X86::EAX;
case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
@@ -760,7 +746,7 @@ unsigned getX86SubSuperRegister(unsigned Reg, EVT VT, bool High) {
}
}
switch (Reg) {
- default: return Reg;
+ default: llvm_unreachable("Unexpected register");
case X86::AH: case X86::AL: case X86::AX: case X86::EAX: case X86::RAX:
return X86::RAX;
case X86::DH: case X86::DL: case X86::DX: case X86::EDX: case X86::RDX:
diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h
index 1bc32cbb78..0287fa2206 100644
--- a/lib/Target/X86/X86RegisterInfo.h
+++ b/lib/Target/X86/X86RegisterInfo.h
@@ -58,10 +58,6 @@ private:
public:
X86RegisterInfo(X86TargetMachine &tm, const TargetInstrInfo &tii);
- /// getX86RegNum - Returns the native X86 register number for the given LLVM
- /// register identifier.
- static unsigned getX86RegNum(unsigned RegNo);
-
// FIXME: This should be tablegen'd like getDwarfRegNum is
int getSEHRegNum(unsigned i) const;
@@ -141,8 +137,8 @@ public:
// getX86SubSuperRegister - X86 utility function. It returns the sub or super
// register of a specific X86 register.
-// e.g. getX86SubSuperRegister(X86::EAX, EVT::i16) return X86:AX
-unsigned getX86SubSuperRegister(unsigned, EVT, bool High=false);
+// e.g. getX86SubSuperRegister(X86::EAX, MVT::i16) return X86:AX
+unsigned getX86SubSuperRegister(unsigned, MVT::SimpleValueType, bool High=false);
} // End llvm namespace
diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td
index febd8851dd..f3bfe9b328 100644
--- a/lib/Target/X86/X86RegisterInfo.td
+++ b/lib/Target/X86/X86RegisterInfo.td
@@ -13,261 +13,267 @@
//
//===----------------------------------------------------------------------===//
-//===----------------------------------------------------------------------===//
-// Register definitions...
-//
-let Namespace = "X86" in {
+class X86Reg<string n, bits<16> Enc, list<Register> subregs = []> : Register<n> {
+ let Namespace = "X86";
+ let HWEncoding = Enc;
+ let SubRegs = subregs;
+}
- // Subregister indices.
+// Subregister indices.
+let Namespace = "X86" in {
def sub_8bit : SubRegIndex;
def sub_8bit_hi : SubRegIndex;
def sub_16bit : SubRegIndex;
def sub_32bit : SubRegIndex;
- def sub_xmm : SubRegIndex;
-
-
- // In the register alias definitions below, we define which registers alias
- // which others. We only specify which registers the small registers alias,
- // because the register file generator is smart enough to figure out that
- // AL aliases AX if we tell it that AX aliased AL (for example).
-
- // Dwarf numbering is different for 32-bit and 64-bit, and there are
- // variations by target as well. Currently the first entry is for X86-64,
- // second - for EH on X86-32/Darwin and third is 'generic' one (X86-32/Linux
- // and debug information on X86-32/Darwin)
-
- // 8-bit registers
- // Low registers
- def AL : Register<"al">;
- def DL : Register<"dl">;
- def CL : Register<"cl">;
- def BL : Register<"bl">;
-
- // X86-64 only, requires REX.
- let CostPerUse = 1 in {
- def SIL : Register<"sil">;
- def DIL : Register<"dil">;
- def BPL : Register<"bpl">;
- def SPL : Register<"spl">;
- def R8B : Register<"r8b">;
- def R9B : Register<"r9b">;
- def R10B : Register<"r10b">;
- def R11B : Register<"r11b">;
- def R12B : Register<"r12b">;
- def R13B : Register<"r13b">;
- def R14B : Register<"r14b">;
- def R15B : Register<"r15b">;
- }
-
- // High registers. On x86-64, these cannot be used in any instruction
- // with a REX prefix.
- def AH : Register<"ah">;
- def DH : Register<"dh">;
- def CH : Register<"ch">;
- def BH : Register<"bh">;
-
- // 16-bit registers
- let SubRegIndices = [sub_8bit, sub_8bit_hi], CoveredBySubRegs = 1 in {
- def AX : RegisterWithSubRegs<"ax", [AL,AH]>;
- def DX : RegisterWithSubRegs<"dx", [DL,DH]>;
- def CX : RegisterWithSubRegs<"cx", [CL,CH]>;
- def BX : RegisterWithSubRegs<"bx", [BL,BH]>;
- }
- let SubRegIndices = [sub_8bit] in {
- def SI : RegisterWithSubRegs<"si", [SIL]>;
- def DI : RegisterWithSubRegs<"di", [DIL]>;
- def BP : RegisterWithSubRegs<"bp", [BPL]>;
- def SP : RegisterWithSubRegs<"sp", [SPL]>;
- }
- def IP : Register<"ip">;
-
- // X86-64 only, requires REX.
- let SubRegIndices = [sub_8bit], CostPerUse = 1 in {
- def R8W : RegisterWithSubRegs<"r8w", [R8B]>;
- def R9W : RegisterWithSubRegs<"r9w", [R9B]>;
- def R10W : RegisterWithSubRegs<"r10w", [R10B]>;
- def R11W : RegisterWithSubRegs<"r11w", [R11B]>;
- def R12W : RegisterWithSubRegs<"r12w", [R12B]>;
- def R13W : RegisterWithSubRegs<"r13w", [R13B]>;
- def R14W : RegisterWithSubRegs<"r14w", [R14B]>;
- def R15W : RegisterWithSubRegs<"r15w", [R15B]>;
- }
- // 32-bit registers
- let SubRegIndices = [sub_16bit] in {
- def EAX : RegisterWithSubRegs<"eax", [AX]>, DwarfRegNum<[-2, 0, 0]>;
- def EDX : RegisterWithSubRegs<"edx", [DX]>, DwarfRegNum<[-2, 2, 2]>;
- def ECX : RegisterWithSubRegs<"ecx", [CX]>, DwarfRegNum<[-2, 1, 1]>;
- def EBX : RegisterWithSubRegs<"ebx", [BX]>, DwarfRegNum<[-2, 3, 3]>;
- def ESI : RegisterWithSubRegs<"esi", [SI]>, DwarfRegNum<[-2, 6, 6]>;
- def EDI : RegisterWithSubRegs<"edi", [DI]>, DwarfRegNum<[-2, 7, 7]>;
- def EBP : RegisterWithSubRegs<"ebp", [BP]>, DwarfRegNum<[-2, 4, 5]>;
- def ESP : RegisterWithSubRegs<"esp", [SP]>, DwarfRegNum<[-2, 5, 4]>;
- def EIP : RegisterWithSubRegs<"eip", [IP]>, DwarfRegNum<[-2, 8, 8]>;
-
- // X86-64 only, requires REX
- let CostPerUse = 1 in {
- def R8D : RegisterWithSubRegs<"r8d", [R8W]>;
- def R9D : RegisterWithSubRegs<"r9d", [R9W]>;
- def R10D : RegisterWithSubRegs<"r10d", [R10W]>;
- def R11D : RegisterWithSubRegs<"r11d", [R11W]>;
- def R12D : RegisterWithSubRegs<"r12d", [R12W]>;
- def R13D : RegisterWithSubRegs<"r13d", [R13W]>;
- def R14D : RegisterWithSubRegs<"r14d", [R14W]>;
- def R15D : RegisterWithSubRegs<"r15d", [R15W]>;
- }}
-
- // 64-bit registers, X86-64 only
- let SubRegIndices = [sub_32bit] in {
- def RAX : RegisterWithSubRegs<"rax", [EAX]>, DwarfRegNum<[0, -2, -2]>;
- def RDX : RegisterWithSubRegs<"rdx", [EDX]>, DwarfRegNum<[1, -2, -2]>;
- def RCX : RegisterWithSubRegs<"rcx", [ECX]>, DwarfRegNum<[2, -2, -2]>;
- def RBX : RegisterWithSubRegs<"rbx", [EBX]>, DwarfRegNum<[3, -2, -2]>;
- def RSI : RegisterWithSubRegs<"rsi", [ESI]>, DwarfRegNum<[4, -2, -2]>;
- def RDI : RegisterWithSubRegs<"rdi", [EDI]>, DwarfRegNum<[5, -2, -2]>;
- def RBP : RegisterWithSubRegs<"rbp", [EBP]>, DwarfRegNum<[6, -2, -2]>;
- def RSP : RegisterWithSubRegs<"rsp", [ESP]>, DwarfRegNum<[7, -2, -2]>;
-
- // These also require REX.
- let CostPerUse = 1 in {
- def R8 : RegisterWithSubRegs<"r8", [R8D]>, DwarfRegNum<[8, -2, -2]>;
- def R9 : RegisterWithSubRegs<"r9", [R9D]>, DwarfRegNum<[9, -2, -2]>;
- def R10 : RegisterWithSubRegs<"r10", [R10D]>, DwarfRegNum<[10, -2, -2]>;
- def R11 : RegisterWithSubRegs<"r11", [R11D]>, DwarfRegNum<[11, -2, -2]>;
- def R12 : RegisterWithSubRegs<"r12", [R12D]>, DwarfRegNum<[12, -2, -2]>;
- def R13 : RegisterWithSubRegs<"r13", [R13D]>, DwarfRegNum<[13, -2, -2]>;
- def R14 : RegisterWithSubRegs<"r14", [R14D]>, DwarfRegNum<[14, -2, -2]>;
- def R15 : RegisterWithSubRegs<"r15", [R15D]>, DwarfRegNum<[15, -2, -2]>;
- def RIP : RegisterWithSubRegs<"rip", [EIP]>, DwarfRegNum<[16, -2, -2]>;
- }}
-
- // MMX Registers. These are actually aliased to ST0 .. ST7
- def MM0 : Register<"mm0">, DwarfRegNum<[41, 29, 29]>;
- def MM1 : Register<"mm1">, DwarfRegNum<[42, 30, 30]>;
- def MM2 : Register<"mm2">, DwarfRegNum<[43, 31, 31]>;
- def MM3 : Register<"mm3">, DwarfRegNum<[44, 32, 32]>;
- def MM4 : Register<"mm4">, DwarfRegNum<[45, 33, 33]>;
- def MM5 : Register<"mm5">, DwarfRegNum<[46, 34, 34]>;
- def MM6 : Register<"mm6">, DwarfRegNum<[47, 35, 35]>;
- def MM7 : Register<"mm7">, DwarfRegNum<[48, 36, 36]>;
-
- // Pseudo Floating Point registers
- def FP0 : Register<"fp0">;
- def FP1 : Register<"fp1">;
- def FP2 : Register<"fp2">;
- def FP3 : Register<"fp3">;
- def FP4 : Register<"fp4">;
- def FP5 : Register<"fp5">;
- def FP6 : Register<"fp6">;
-
- // XMM Registers, used by the various SSE instruction set extensions.
- def XMM0: Register<"xmm0">, DwarfRegNum<[17, 21, 21]>;
- def XMM1: Register<"xmm1">, DwarfRegNum<[18, 22, 22]>;
- def XMM2: Register<"xmm2">, DwarfRegNum<[19, 23, 23]>;
- def XMM3: Register<"xmm3">, DwarfRegNum<[20, 24, 24]>;
- def XMM4: Register<"xmm4">, DwarfRegNum<[21, 25, 25]>;
- def XMM5: Register<"xmm5">, DwarfRegNum<[22, 26, 26]>;
- def XMM6: Register<"xmm6">, DwarfRegNum<[23, 27, 27]>;
- def XMM7: Register<"xmm7">, DwarfRegNum<[24, 28, 28]>;
-
- // X86-64 only
- let CostPerUse = 1 in {
- def XMM8: Register<"xmm8">, DwarfRegNum<[25, -2, -2]>;
- def XMM9: Register<"xmm9">, DwarfRegNum<[26, -2, -2]>;
- def XMM10: Register<"xmm10">, DwarfRegNum<[27, -2, -2]>;
- def XMM11: Register<"xmm11">, DwarfRegNum<[28, -2, -2]>;
- def XMM12: Register<"xmm12">, DwarfRegNum<[29, -2, -2]>;
- def XMM13: Register<"xmm13">, DwarfRegNum<[30, -2, -2]>;
- def XMM14: Register<"xmm14">, DwarfRegNum<[31, -2, -2]>;
- def XMM15: Register<"xmm15">, DwarfRegNum<[32, -2, -2]>;
- } // CostPerUse
-
- // YMM Registers, used by AVX instructions
- let SubRegIndices = [sub_xmm] in {
- def YMM0: RegisterWithSubRegs<"ymm0", [XMM0]>, DwarfRegAlias<XMM0>;
- def YMM1: RegisterWithSubRegs<"ymm1", [XMM1]>, DwarfRegAlias<XMM1>;
- def YMM2: RegisterWithSubRegs<"ymm2", [XMM2]>, DwarfRegAlias<XMM2>;
- def YMM3: RegisterWithSubRegs<"ymm3", [XMM3]>, DwarfRegAlias<XMM3>;
- def YMM4: RegisterWithSubRegs<"ymm4", [XMM4]>, DwarfRegAlias<XMM4>;
- def YMM5: RegisterWithSubRegs<"ymm5", [XMM5]>, DwarfRegAlias<XMM5>;
- def YMM6: RegisterWithSubRegs<"ymm6", [XMM6]>, DwarfRegAlias<XMM6>;
- def YMM7: RegisterWithSubRegs<"ymm7", [XMM7]>, DwarfRegAlias<XMM7>;
- def YMM8: RegisterWithSubRegs<"ymm8", [XMM8]>, DwarfRegAlias<XMM8>;
- def YMM9: RegisterWithSubRegs<"ymm9", [XMM9]>, DwarfRegAlias<XMM9>;
- def YMM10: RegisterWithSubRegs<"ymm10", [XMM10]>, DwarfRegAlias<XMM10>;
- def YMM11: RegisterWithSubRegs<"ymm11", [XMM11]>, DwarfRegAlias<XMM11>;
- def YMM12: RegisterWithSubRegs<"ymm12", [XMM12]>, DwarfRegAlias<XMM12>;
- def YMM13: RegisterWithSubRegs<"ymm13", [XMM13]>, DwarfRegAlias<XMM13>;
- def YMM14: RegisterWithSubRegs<"ymm14", [XMM14]>, DwarfRegAlias<XMM14>;
- def YMM15: RegisterWithSubRegs<"ymm15", [XMM15]>, DwarfRegAlias<XMM15>;
- }
-
- class STRegister<string Name, list<Register> A> : Register<Name> {
- let Aliases = A;
- }
-
- // Floating point stack registers. These don't map one-to-one to the FP
- // pseudo registers, but we still mark them as aliasing FP registers. That
- // way both kinds can be live without exceeding the stack depth. ST registers
- // are only live around inline assembly.
- def ST0 : STRegister<"st(0)", []>, DwarfRegNum<[33, 12, 11]>;
- def ST1 : STRegister<"st(1)", [FP6]>, DwarfRegNum<[34, 13, 12]>;
- def ST2 : STRegister<"st(2)", [FP5]>, DwarfRegNum<[35, 14, 13]>;
- def ST3 : STRegister<"st(3)", [FP4]>, DwarfRegNum<[36, 15, 14]>;
- def ST4 : STRegister<"st(4)", [FP3]>, DwarfRegNum<[37, 16, 15]>;
- def ST5 : STRegister<"st(5)", [FP2]>, DwarfRegNum<[38, 17, 16]>;
- def ST6 : STRegister<"st(6)", [FP1]>, DwarfRegNum<[39, 18, 17]>;
- def ST7 : STRegister<"st(7)", [FP0]>, DwarfRegNum<[40, 19, 18]>;
-
- // Floating-point status word
- def FPSW : Register<"fpsw">;
-
- // Status flags register
- def EFLAGS : Register<"flags">;
-
- // Segment registers
- def CS : Register<"cs">;
- def DS : Register<"ds">;
- def SS : Register<"ss">;
- def ES : Register<"es">;
- def FS : Register<"fs">;
- def GS : Register<"gs">;
-
- // Debug registers
- def DR0 : Register<"dr0">;
- def DR1 : Register<"dr1">;
- def DR2 : Register<"dr2">;
- def DR3 : Register<"dr3">;
- def DR4 : Register<"dr4">;
- def DR5 : Register<"dr5">;
- def DR6 : Register<"dr6">;
- def DR7 : Register<"dr7">;
-
- // Control registers
- def CR0 : Register<"cr0">;
- def CR1 : Register<"cr1">;
- def CR2 : Register<"cr2">;
- def CR3 : Register<"cr3">;
- def CR4 : Register<"cr4">;
- def CR5 : Register<"cr5">;
- def CR6 : Register<"cr6">;
- def CR7 : Register<"cr7">;
- def CR8 : Register<"cr8">;
- def CR9 : Register<"cr9">;
- def CR10 : Register<"cr10">;
- def CR11 : Register<"cr11">;
- def CR12 : Register<"cr12">;
- def CR13 : Register<"cr13">;
- def CR14 : Register<"cr14">;
- def CR15 : Register<"cr15">;
-
- // Pseudo index registers
- def EIZ : Register<"eiz">;
- def RIZ : Register<"riz">;
-
- def PSEUDO_NACL_SEG : Register<"nacl">; // @LOCALMOD
+ def sub_xmm : SubRegIndex;
+}
+
+//===----------------------------------------------------------------------===//
+// Register definitions...
+//
+// In the register alias definitions below, we define which registers alias
+// which others. We only specify which registers the small registers alias,
+// because the register file generator is smart enough to figure out that
+// AL aliases AX if we tell it that AX aliased AL (for example).
+
+// Dwarf numbering is different for 32-bit and 64-bit, and there are
+// variations by target as well. Currently the first entry is for X86-64,
+// second - for EH on X86-32/Darwin and third is 'generic' one (X86-32/Linux
+// and debug information on X86-32/Darwin)
+
+// 8-bit registers
+// Low registers
+def AL : X86Reg<"al", 0>;
+def DL : X86Reg<"dl", 2>;
+def CL : X86Reg<"cl", 1>;
+def BL : X86Reg<"bl", 3>;
+
+// High registers. On x86-64, these cannot be used in any instruction
+// with a REX prefix.
+def AH : X86Reg<"ah", 4>;
+def DH : X86Reg<"dh", 6>;
+def CH : X86Reg<"ch", 5>;
+def BH : X86Reg<"bh", 7>;
+
+// X86-64 only, requires REX.
+let CostPerUse = 1 in {
+def SIL : X86Reg<"sil", 6>;
+def DIL : X86Reg<"dil", 7>;
+def BPL : X86Reg<"bpl", 5>;
+def SPL : X86Reg<"spl", 4>;
+def R8B : X86Reg<"r8b", 8>;
+def R9B : X86Reg<"r9b", 9>;
+def R10B : X86Reg<"r10b", 10>;
+def R11B : X86Reg<"r11b", 11>;
+def R12B : X86Reg<"r12b", 12>;
+def R13B : X86Reg<"r13b", 13>;
+def R14B : X86Reg<"r14b", 14>;
+def R15B : X86Reg<"r15b", 15>;
}
+// 16-bit registers
+let SubRegIndices = [sub_8bit, sub_8bit_hi], CoveredBySubRegs = 1 in {
+def AX : X86Reg<"ax", 0, [AL,AH]>;
+def DX : X86Reg<"dx", 2, [DL,DH]>;
+def CX : X86Reg<"cx", 1, [CL,CH]>;
+def BX : X86Reg<"bx", 3, [BL,BH]>;
+}
+let SubRegIndices = [sub_8bit] in {
+def SI : X86Reg<"si", 6, [SIL]>;
+def DI : X86Reg<"di", 7, [DIL]>;
+def BP : X86Reg<"bp", 5, [BPL]>;
+def SP : X86Reg<"sp", 4, [SPL]>;
+}
+def IP : X86Reg<"ip", 0>;
+
+// X86-64 only, requires REX.
+let SubRegIndices = [sub_8bit], CostPerUse = 1 in {
+def R8W : X86Reg<"r8w", 8, [R8B]>;
+def R9W : X86Reg<"r9w", 9, [R9B]>;
+def R10W : X86Reg<"r10w", 10, [R10B]>;
+def R11W : X86Reg<"r11w", 11, [R11B]>;
+def R12W : X86Reg<"r12w", 12, [R12B]>;
+def R13W : X86Reg<"r13w", 13, [R13B]>;
+def R14W : X86Reg<"r14w", 14, [R14B]>;
+def R15W : X86Reg<"r15w", 15, [R15B]>;
+}
+
+// 32-bit registers
+let SubRegIndices = [sub_16bit] in {
+def EAX : X86Reg<"eax", 0, [AX]>, DwarfRegNum<[-2, 0, 0]>;
+def EDX : X86Reg<"edx", 2, [DX]>, DwarfRegNum<[-2, 2, 2]>;
+def ECX : X86Reg<"ecx", 1, [CX]>, DwarfRegNum<[-2, 1, 1]>;
+def EBX : X86Reg<"ebx", 3, [BX]>, DwarfRegNum<[-2, 3, 3]>;
+def ESI : X86Reg<"esi", 6, [SI]>, DwarfRegNum<[-2, 6, 6]>;
+def EDI : X86Reg<"edi", 7, [DI]>, DwarfRegNum<[-2, 7, 7]>;
+def EBP : X86Reg<"ebp", 5, [BP]>, DwarfRegNum<[-2, 4, 5]>;
+def ESP : X86Reg<"esp", 4, [SP]>, DwarfRegNum<[-2, 5, 4]>;
+def EIP : X86Reg<"eip", 0, [IP]>, DwarfRegNum<[-2, 8, 8]>;
+
+// X86-64 only, requires REX
+let CostPerUse = 1 in {
+def R8D : X86Reg<"r8d", 8, [R8W]>;
+def R9D : X86Reg<"r9d", 9, [R9W]>;
+def R10D : X86Reg<"r10d", 10, [R10W]>;
+def R11D : X86Reg<"r11d", 11, [R11W]>;
+def R12D : X86Reg<"r12d", 12, [R12W]>;
+def R13D : X86Reg<"r13d", 13, [R13W]>;
+def R14D : X86Reg<"r14d", 14, [R14W]>;
+def R15D : X86Reg<"r15d", 15, [R15W]>;
+}}
+
+// 64-bit registers, X86-64 only
+let SubRegIndices = [sub_32bit] in {
+def RAX : X86Reg<"rax", 0, [EAX]>, DwarfRegNum<[0, -2, -2]>;
+def RDX : X86Reg<"rdx", 2, [EDX]>, DwarfRegNum<[1, -2, -2]>;
+def RCX : X86Reg<"rcx", 1, [ECX]>, DwarfRegNum<[2, -2, -2]>;
+def RBX : X86Reg<"rbx", 3, [EBX]>, DwarfRegNum<[3, -2, -2]>;
+def RSI : X86Reg<"rsi", 6, [ESI]>, DwarfRegNum<[4, -2, -2]>;
+def RDI : X86Reg<"rdi", 7, [EDI]>, DwarfRegNum<[5, -2, -2]>;
+def RBP : X86Reg<"rbp", 5, [EBP]>, DwarfRegNum<[6, -2, -2]>;
+def RSP : X86Reg<"rsp", 4, [ESP]>, DwarfRegNum<[7, -2, -2]>;
+
+// These also require REX.
+let CostPerUse = 1 in {
+def R8 : X86Reg<"r8", 8, [R8D]>, DwarfRegNum<[ 8, -2, -2]>;
+def R9 : X86Reg<"r9", 9, [R9D]>, DwarfRegNum<[ 9, -2, -2]>;
+def R10 : X86Reg<"r10", 10, [R10D]>, DwarfRegNum<[10, -2, -2]>;
+def R11 : X86Reg<"r11", 11, [R11D]>, DwarfRegNum<[11, -2, -2]>;
+def R12 : X86Reg<"r12", 12, [R12D]>, DwarfRegNum<[12, -2, -2]>;
+def R13 : X86Reg<"r13", 13, [R13D]>, DwarfRegNum<[13, -2, -2]>;
+def R14 : X86Reg<"r14", 14, [R14D]>, DwarfRegNum<[14, -2, -2]>;
+def R15 : X86Reg<"r15", 15, [R15D]>, DwarfRegNum<[15, -2, -2]>;
+def RIP : X86Reg<"rip", 0, [EIP]>, DwarfRegNum<[16, -2, -2]>;
+}}
+
+// MMX Registers. These are actually aliased to ST0 .. ST7
+def MM0 : X86Reg<"mm0", 0>, DwarfRegNum<[41, 29, 29]>;
+def MM1 : X86Reg<"mm1", 1>, DwarfRegNum<[42, 30, 30]>;
+def MM2 : X86Reg<"mm2", 2>, DwarfRegNum<[43, 31, 31]>;
+def MM3 : X86Reg<"mm3", 3>, DwarfRegNum<[44, 32, 32]>;
+def MM4 : X86Reg<"mm4", 4>, DwarfRegNum<[45, 33, 33]>;
+def MM5 : X86Reg<"mm5", 5>, DwarfRegNum<[46, 34, 34]>;
+def MM6 : X86Reg<"mm6", 6>, DwarfRegNum<[47, 35, 35]>;
+def MM7 : X86Reg<"mm7", 7>, DwarfRegNum<[48, 36, 36]>;
+
+// Pseudo Floating Point registers
+def FP0 : X86Reg<"fp0", 0>;
+def FP1 : X86Reg<"fp1", 0>;
+def FP2 : X86Reg<"fp2", 0>;
+def FP3 : X86Reg<"fp3", 0>;
+def FP4 : X86Reg<"fp4", 0>;
+def FP5 : X86Reg<"fp5", 0>;
+def FP6 : X86Reg<"fp6", 0>;
+
+// XMM Registers, used by the various SSE instruction set extensions.
+def XMM0: X86Reg<"xmm0", 0>, DwarfRegNum<[17, 21, 21]>;
+def XMM1: X86Reg<"xmm1", 1>, DwarfRegNum<[18, 22, 22]>;
+def XMM2: X86Reg<"xmm2", 2>, DwarfRegNum<[19, 23, 23]>;
+def XMM3: X86Reg<"xmm3", 3>, DwarfRegNum<[20, 24, 24]>;
+def XMM4: X86Reg<"xmm4", 4>, DwarfRegNum<[21, 25, 25]>;
+def XMM5: X86Reg<"xmm5", 5>, DwarfRegNum<[22, 26, 26]>;
+def XMM6: X86Reg<"xmm6", 6>, DwarfRegNum<[23, 27, 27]>;
+def XMM7: X86Reg<"xmm7", 7>, DwarfRegNum<[24, 28, 28]>;
+
+// X86-64 only
+let CostPerUse = 1 in {
+def XMM8: X86Reg<"xmm8", 8>, DwarfRegNum<[25, -2, -2]>;
+def XMM9: X86Reg<"xmm9", 9>, DwarfRegNum<[26, -2, -2]>;
+def XMM10: X86Reg<"xmm10", 10>, DwarfRegNum<[27, -2, -2]>;
+def XMM11: X86Reg<"xmm11", 11>, DwarfRegNum<[28, -2, -2]>;
+def XMM12: X86Reg<"xmm12", 12>, DwarfRegNum<[29, -2, -2]>;
+def XMM13: X86Reg<"xmm13", 13>, DwarfRegNum<[30, -2, -2]>;
+def XMM14: X86Reg<"xmm14", 14>, DwarfRegNum<[31, -2, -2]>;
+def XMM15: X86Reg<"xmm15", 15>, DwarfRegNum<[32, -2, -2]>;
+} // CostPerUse
+
+// YMM Registers, used by AVX instructions
+let SubRegIndices = [sub_xmm] in {
+def YMM0: X86Reg<"ymm0", 0, [XMM0]>, DwarfRegAlias<XMM0>;
+def YMM1: X86Reg<"ymm1", 1, [XMM1]>, DwarfRegAlias<XMM1>;
+def YMM2: X86Reg<"ymm2", 2, [XMM2]>, DwarfRegAlias<XMM2>;
+def YMM3: X86Reg<"ymm3", 3, [XMM3]>, DwarfRegAlias<XMM3>;
+def YMM4: X86Reg<"ymm4", 4, [XMM4]>, DwarfRegAlias<XMM4>;
+def YMM5: X86Reg<"ymm5", 5, [XMM5]>, DwarfRegAlias<XMM5>;
+def YMM6: X86Reg<"ymm6", 6, [XMM6]>, DwarfRegAlias<XMM6>;
+def YMM7: X86Reg<"ymm7", 7, [XMM7]>, DwarfRegAlias<XMM7>;
+def YMM8: X86Reg<"ymm8", 8, [XMM8]>, DwarfRegAlias<XMM8>;
+def YMM9: X86Reg<"ymm9", 9, [XMM9]>, DwarfRegAlias<XMM9>;
+def YMM10: X86Reg<"ymm10", 10, [XMM10]>, DwarfRegAlias<XMM10>;
+def YMM11: X86Reg<"ymm11", 11, [XMM11]>, DwarfRegAlias<XMM11>;
+def YMM12: X86Reg<"ymm12", 12, [XMM12]>, DwarfRegAlias<XMM12>;
+def YMM13: X86Reg<"ymm13", 13, [XMM13]>, DwarfRegAlias<XMM13>;
+def YMM14: X86Reg<"ymm14", 14, [XMM14]>, DwarfRegAlias<XMM14>;
+def YMM15: X86Reg<"ymm15", 15, [XMM15]>, DwarfRegAlias<XMM15>;
+}
+
+class STRegister<string n, bits<16> Enc, list<Register> A> : X86Reg<n, Enc> {
+ let Aliases = A;
+}
+
+// Floating point stack registers. These don't map one-to-one to the FP
+// pseudo registers, but we still mark them as aliasing FP registers. That
+// way both kinds can be live without exceeding the stack depth. ST registers
+// are only live around inline assembly.
+def ST0 : STRegister<"st(0)", 0, []>, DwarfRegNum<[33, 12, 11]>;
+def ST1 : STRegister<"st(1)", 1, [FP6]>, DwarfRegNum<[34, 13, 12]>;
+def ST2 : STRegister<"st(2)", 2, [FP5]>, DwarfRegNum<[35, 14, 13]>;
+def ST3 : STRegister<"st(3)", 3, [FP4]>, DwarfRegNum<[36, 15, 14]>;
+def ST4 : STRegister<"st(4)", 4, [FP3]>, DwarfRegNum<[37, 16, 15]>;
+def ST5 : STRegister<"st(5)", 5, [FP2]>, DwarfRegNum<[38, 17, 16]>;
+def ST6 : STRegister<"st(6)", 6, [FP1]>, DwarfRegNum<[39, 18, 17]>;
+def ST7 : STRegister<"st(7)", 7, [FP0]>, DwarfRegNum<[40, 19, 18]>;
+
+// Floating-point status word
+def FPSW : X86Reg<"fpsw", 0>;
+
+// Status flags register
+def EFLAGS : X86Reg<"flags", 0>;
+
+// Segment registers
+def CS : X86Reg<"cs", 1>;
+def DS : X86Reg<"ds", 3>;
+def SS : X86Reg<"ss", 2>;
+def ES : X86Reg<"es", 0>;
+def FS : X86Reg<"fs", 4>;
+def GS : X86Reg<"gs", 5>;
+
+// Debug registers
+def DR0 : X86Reg<"dr0", 0>;
+def DR1 : X86Reg<"dr1", 1>;
+def DR2 : X86Reg<"dr2", 2>;
+def DR3 : X86Reg<"dr3", 3>;
+def DR4 : X86Reg<"dr4", 4>;
+def DR5 : X86Reg<"dr5", 5>;
+def DR6 : X86Reg<"dr6", 6>;
+def DR7 : X86Reg<"dr7", 7>;
+
+// Control registers
+def CR0 : X86Reg<"cr0", 0>;
+def CR1 : X86Reg<"cr1", 1>;
+def CR2 : X86Reg<"cr2", 2>;
+def CR3 : X86Reg<"cr3", 3>;
+def CR4 : X86Reg<"cr4", 4>;
+def CR5 : X86Reg<"cr5", 5>;
+def CR6 : X86Reg<"cr6", 6>;
+def CR7 : X86Reg<"cr7", 7>;
+def CR8 : X86Reg<"cr8", 8>;
+def CR9 : X86Reg<"cr9", 9>;
+def CR10 : X86Reg<"cr10", 10>;
+def CR11 : X86Reg<"cr11", 11>;
+def CR12 : X86Reg<"cr12", 12>;
+def CR13 : X86Reg<"cr13", 13>;
+def CR14 : X86Reg<"cr14", 14>;
+def CR15 : X86Reg<"cr15", 15>;
+
+// Pseudo index registers
+def EIZ : X86Reg<"eiz", 4>;
+def RIZ : X86Reg<"riz", 4>;
+
+def PSEUDO_NACL_SEG : X86Reg<"nacl", 4>; // @LOCALMOD
+
+
//===----------------------------------------------------------------------===//
// Register Class Definitions... now that we have all of the pieces, define the
diff --git a/lib/Target/X86/X86SelectionDAGInfo.cpp b/lib/Target/X86/X86SelectionDAGInfo.cpp
index 3018654cb6..a102935b4b 100644
--- a/lib/Target/X86/X86SelectionDAGInfo.cpp
+++ b/lib/Target/X86/X86SelectionDAGInfo.cpp
@@ -62,7 +62,7 @@ X86SelectionDAGInfo::EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
if (const char *bzeroEntry = V &&
V->isNullValue() ? Subtarget->getBZeroEntry() : 0) {
EVT IntPtr = TLI.getPointerTy();
- Type *IntPtrTy = getTargetData()->getIntPtrType(*DAG.getContext());
+ Type *IntPtrTy = getDataLayout()->getIntPtrType(*DAG.getContext());
TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry;
Entry.Node = Dst;
diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp
index 610e7ed7f3..177dfa02b4 100644
--- a/lib/Target/X86/X86Subtarget.cpp
+++ b/lib/Target/X86/X86Subtarget.cpp
@@ -167,17 +167,6 @@ bool X86Subtarget::IsLegalToCallImmediateAddr(const TargetMachine &TM) const {
// @LOCALMOD-END
}
-/// getSpecialAddressLatency - For targets where it is beneficial to
-/// backschedule instructions that compute addresses, return a value
-/// indicating the number of scheduling cycles of backscheduling that
-/// should be attempted.
-unsigned X86Subtarget::getSpecialAddressLatency() const {
- // For x86 out-of-order targets, back-schedule address computations so
- // that loads and stores aren't blocked.
- // This value was chosen arbitrarily.
- return 200;
-}
-
void X86Subtarget::AutoDetectSubtargetFeatures() {
unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
unsigned MaxLevel;
@@ -405,6 +394,10 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &CPU,
}
}
+ // CPUName may have been set by the CPU detection code. Make sure the
+ // new MCSchedModel is used.
+ InitMCProcessorInfo(CPUName, FS);
+
if (X86ProcFamily == IntelAtom)
PostRAScheduler = true;
diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h
index 921ded8f2d..a9ce62640e 100644
--- a/lib/Target/X86/X86Subtarget.h
+++ b/lib/Target/X86/X86Subtarget.h
@@ -240,10 +240,10 @@ public:
bool isTargetSolaris() const {
return TargetTriple.getOS() == Triple::Solaris;
}
-
- // ELF is a reasonably sane default and the only other X86 targets we
- // support are Darwin and Windows. Just use "not those".
- bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
+ bool isTargetELF() const {
+ return (TargetTriple.getEnvironment() == Triple::ELF ||
+ TargetTriple.isOSBinFormatELF());
+ }
bool isTargetLinux() const { return TargetTriple.getOS() == Triple::Linux; }
bool isTargetNaCl() const {
return TargetTriple.getOS() == Triple::NativeClient;
@@ -254,7 +254,10 @@ public:
bool isTargetMingw() const { return TargetTriple.getOS() == Triple::MinGW32; }
bool isTargetCygwin() const { return TargetTriple.getOS() == Triple::Cygwin; }
bool isTargetCygMing() const { return TargetTriple.isOSCygMing(); }
- bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
+ bool isTargetCOFF() const {
+ return (TargetTriple.getEnvironment() != Triple::ELF &&
+ TargetTriple.isOSBinFormatCOFF());
+ }
bool isTargetEnvMacho() const { return TargetTriple.isEnvironmentMachO(); }
bool isTargetWin64() const {
@@ -305,12 +308,6 @@ public:
/// returns null.
const char *getBZeroEntry() const;
- /// getSpecialAddressLatency - For targets where it is beneficial to
- /// backschedule instructions that compute addresses, return a value
- /// indicating the number of scheduling cycles of backscheduling that
- /// should be attempted.
- unsigned getSpecialAddressLatency() const;
-
/// enablePostRAScheduler - run for Atom optimization.
bool enablePostRAScheduler(CodeGenOpt::Level OptLevel,
TargetSubtargetInfo::AntiDepBreakMode& Mode,
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index df4aefbe3d..ed5e6f5227 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -36,7 +36,7 @@ X86_32TargetMachine::X86_32TargetMachine(const Target &T, StringRef TT,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL)
: X86TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false),
- DataLayout(getSubtargetImpl()->isTargetDarwin() ?
+ DL(getSubtargetImpl()->isTargetDarwin() ?
"e-p:32:32-f64:32:64-i64:32:64-f80:128:128-f128:128:128-"
"n8:16:32-S128" :
(getSubtargetImpl()->isTargetCygMing() ||
@@ -61,7 +61,7 @@ X86_64TargetMachine::X86_64TargetMachine(const Target &T, StringRef TT,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL)
: X86TargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true),
- DataLayout(getSubtargetImpl()->isTargetNaCl() ? // @LOCALMOD
+ DL(getSubtargetImpl()->isTargetNaCl() ? // @LOCALMOD
"e-p:32:32-s:64-f64:64:64-f32:32:32-f80:128:128-i64:64:64-"
"n8:16:32:64-S128" :
"e-p:64:64-s:64-f64:64:64-i64:64:64-f80:128:128-f128:128:128-"
@@ -118,6 +118,12 @@ UseVZeroUpper("x86-use-vzeroupper",
cl::desc("Minimize AVX to SSE transition penalty"),
cl::init(true));
+// Temporary option to control early if-conversion for x86 while adding machine
+// models.
+static cl::opt<bool>
+X86EarlyIfConv("x86-early-ifcvt",
+ cl::desc("Enable early if-conversion on X86"));
+
//===----------------------------------------------------------------------===//
// Pass Pipeline Configuration
//===----------------------------------------------------------------------===//
@@ -147,7 +153,7 @@ public:
TargetPassConfig *X86TargetMachine::createPassConfig(PassManagerBase &PM) {
X86PassConfig *PC = new X86PassConfig(this, PM);
- if (Subtarget.hasCMov())
+ if (X86EarlyIfConv && Subtarget.hasCMov())
PC->enablePass(&EarlyIfConverterID);
return PC;
diff --git a/lib/Target/X86/X86TargetMachine.h b/lib/Target/X86/X86TargetMachine.h
index d4552d8136..5c625ac953 100644
--- a/lib/Target/X86/X86TargetMachine.h
+++ b/lib/Target/X86/X86TargetMachine.h
@@ -26,7 +26,7 @@
#include "X86SelectionDAGInfo.h"
#include "X86Subtarget.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetFrameLowering.h"
namespace llvm {
@@ -83,7 +83,7 @@ public:
///
class X86_32TargetMachine : public X86TargetMachine {
virtual void anchor();
- const TargetData DataLayout; // Calculates type size & alignment
+ const DataLayout DL; // Calculates type size & alignment
X86InstrInfo InstrInfo;
X86SelectionDAGInfo TSInfo;
X86TargetLowering TLInfo;
@@ -97,7 +97,7 @@ public:
StringRef CPU, StringRef FS, const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL);
- virtual const TargetData *getTargetData() const { return &DataLayout; }
+ virtual const DataLayout *getDataLayout() const { return &DL; }
virtual const X86TargetLowering *getTargetLowering() const {
return &TLInfo;
}
@@ -116,7 +116,7 @@ public:
///
class X86_64TargetMachine : public X86TargetMachine {
virtual void anchor();
- const TargetData DataLayout; // Calculates type size & alignment
+ const DataLayout DL; // Calculates type size & alignment
X86InstrInfo InstrInfo;
X86SelectionDAGInfo TSInfo;
X86TargetLowering TLInfo;
@@ -126,7 +126,7 @@ public:
StringRef CPU, StringRef FS, const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL);
- virtual const TargetData *getTargetData() const { return &DataLayout; }
+ virtual const DataLayout *getDataLayout() const { return &DL; }
virtual const X86TargetLowering *getTargetLowering() const {
return &TLInfo;
}
diff --git a/lib/Target/XCore/XCoreAsmPrinter.cpp b/lib/Target/XCore/XCoreAsmPrinter.cpp
index c76866f47b..caae562272 100644
--- a/lib/Target/XCore/XCoreAsmPrinter.cpp
+++ b/lib/Target/XCore/XCoreAsmPrinter.cpp
@@ -31,7 +31,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
@@ -112,7 +112,7 @@ void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
EmitSpecialLLVMGlobal(GV))
return;
- const TargetData *TD = TM.getTargetData();
+ const DataLayout *TD = TM.getDataLayout();
OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GV, Mang,TM));
diff --git a/lib/Target/XCore/XCoreFrameLowering.cpp b/lib/Target/XCore/XCoreFrameLowering.cpp
index a4e56472ba..e18d97384d 100644
--- a/lib/Target/XCore/XCoreFrameLowering.cpp
+++ b/lib/Target/XCore/XCoreFrameLowering.cpp
@@ -23,7 +23,7 @@
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/ErrorHandling.h"
@@ -98,12 +98,13 @@ void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const {
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
bool FP = hasFP(MF);
- bool Nested = MF.getFunction()->
- getAttributes().hasAttrSomewhere(Attribute::Nest);
+ const AttrListPtr &PAL = MF.getFunction()->getAttributes();
- if (Nested) {
- loadFromStack(MBB, MBBI, XCore::R11, 0, dl, TII);
- }
+ for (unsigned I = 0, E = PAL.getNumAttrs(); I != E; ++I)
+ if (PAL.getAttributesAtIndex(I).hasAttribute(Attributes::Nest)) {
+ loadFromStack(MBB, MBBI, XCore::R11, 0, dl, TII);
+ break;
+ }
// Work out frame sizes.
int FrameSize = MFI->getStackSize();
diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp
index 3695ce2324..9e7816e21f 100644
--- a/lib/Target/XCore/XCoreISelLowering.cpp
+++ b/lib/Target/XCore/XCoreISelLowering.cpp
@@ -285,7 +285,7 @@ LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const
llvm_unreachable(0);
}
SDValue base = getGlobalAddressWrapper(GA, GV, DAG);
- const TargetData *TD = TM.getTargetData();
+ const DataLayout *TD = TM.getDataLayout();
unsigned Size = TD->getTypeAllocSize(Ty);
SDValue offset = DAG.getNode(ISD::MUL, dl, MVT::i32, BuildGetId(DAG, dl),
DAG.getConstant(Size, MVT::i32));
@@ -405,7 +405,7 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG) const {
if (allowsUnalignedMemoryAccesses(LD->getMemoryVT()))
return SDValue();
- unsigned ABIAlignment = getTargetData()->
+ unsigned ABIAlignment = getDataLayout()->
getABITypeAlignment(LD->getMemoryVT().getTypeForEVT(*DAG.getContext()));
// Leave aligned load alone.
if (LD->getAlignment() >= ABIAlignment)
@@ -477,7 +477,7 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG) const {
}
// Lower to a call to __misaligned_load(BasePtr).
- Type *IntPtrTy = getTargetData()->getIntPtrType(*DAG.getContext());
+ Type *IntPtrTy = getDataLayout()->getIntPtrType(*DAG.getContext());
TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry;
@@ -507,7 +507,7 @@ LowerSTORE(SDValue Op, SelectionDAG &DAG) const
if (allowsUnalignedMemoryAccesses(ST->getMemoryVT())) {
return SDValue();
}
- unsigned ABIAlignment = getTargetData()->
+ unsigned ABIAlignment = getDataLayout()->
getABITypeAlignment(ST->getMemoryVT().getTypeForEVT(*DAG.getContext()));
// Leave aligned store alone.
if (ST->getAlignment() >= ABIAlignment) {
@@ -536,7 +536,7 @@ LowerSTORE(SDValue Op, SelectionDAG &DAG) const
}
// Lower to a call to __misaligned_store(BasePtr, Value).
- Type *IntPtrTy = getTargetData()->getIntPtrType(*DAG.getContext());
+ Type *IntPtrTy = getDataLayout()->getIntPtrType(*DAG.getContext());
TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry;
@@ -1499,7 +1499,7 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N,
if (StoreBits % 8) {
break;
}
- unsigned ABIAlignment = getTargetData()->getABITypeAlignment(
+ unsigned ABIAlignment = getDataLayout()->getABITypeAlignment(
ST->getMemoryVT().getTypeForEVT(*DCI.DAG.getContext()));
unsigned Alignment = ST->getAlignment();
if (Alignment >= ABIAlignment) {
@@ -1570,7 +1570,7 @@ XCoreTargetLowering::isLegalAddressingMode(const AddrMode &AM,
if (Ty->getTypeID() == Type::VoidTyID)
return AM.Scale == 0 && isImmUs(AM.BaseOffs) && isImmUs4(AM.BaseOffs);
- const TargetData *TD = TM.getTargetData();
+ const DataLayout *TD = TM.getDataLayout();
unsigned Size = TD->getTypeAllocSize(Ty);
if (AM.BaseGV) {
return Size >= 4 && !AM.HasBaseReg && AM.Scale == 0 &&
diff --git a/lib/Target/XCore/XCoreTargetMachine.cpp b/lib/Target/XCore/XCoreTargetMachine.cpp
index 11ec86b0fa..c71d978ad8 100644
--- a/lib/Target/XCore/XCoreTargetMachine.cpp
+++ b/lib/Target/XCore/XCoreTargetMachine.cpp
@@ -27,7 +27,7 @@ XCoreTargetMachine::XCoreTargetMachine(const Target &T, StringRef TT,
CodeGenOpt::Level OL)
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
Subtarget(TT, CPU, FS),
- DataLayout("e-p:32:32:32-a0:0:32-f32:32:32-f64:32:32-i1:8:32-i8:8:32-"
+ DL("e-p:32:32:32-a0:0:32-f32:32:32-f64:32:32-i1:8:32-i8:8:32-"
"i16:16:32-i32:32:32-i64:32:32-n32"),
InstrInfo(),
FrameLowering(Subtarget),
diff --git a/lib/Target/XCore/XCoreTargetMachine.h b/lib/Target/XCore/XCoreTargetMachine.h
index 254668142a..f7fec29f54 100644
--- a/lib/Target/XCore/XCoreTargetMachine.h
+++ b/lib/Target/XCore/XCoreTargetMachine.h
@@ -20,13 +20,13 @@
#include "XCoreISelLowering.h"
#include "XCoreSelectionDAGInfo.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
namespace llvm {
class XCoreTargetMachine : public LLVMTargetMachine {
XCoreSubtarget Subtarget;
- const TargetData DataLayout; // Calculates type size & alignment
+ const DataLayout DL; // Calculates type size & alignment
XCoreInstrInfo InstrInfo;
XCoreFrameLowering FrameLowering;
XCoreTargetLowering TLInfo;
@@ -53,7 +53,7 @@ public:
virtual const TargetRegisterInfo *getRegisterInfo() const {
return &InstrInfo.getRegisterInfo();
}
- virtual const TargetData *getTargetData() const { return &DataLayout; }
+ virtual const DataLayout *getDataLayout() const { return &DL; }
// Pass Pipeline Configuration
virtual TargetPassConfig *createPassConfig(PassManagerBase &PM);
diff --git a/lib/Transforms/IPO/ArgumentPromotion.cpp b/lib/Transforms/IPO/ArgumentPromotion.cpp
index 10f5b6e658..6f6ff9ca2d 100644
--- a/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ b/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -153,7 +153,8 @@ CallGraphNode *ArgPromotion::PromoteArguments(CallGraphNode *CGN) {
SmallPtrSet<Argument*, 8> ArgsToPromote;
SmallPtrSet<Argument*, 8> ByValArgsToTransform;
for (unsigned i = 0; i != PointerArgs.size(); ++i) {
- bool isByVal = F->paramHasAttr(PointerArgs[i].second+1, Attribute::ByVal);
+ bool isByVal=F->getParamAttributes(PointerArgs[i].second+1).
+ hasAttribute(Attributes::ByVal);
Argument *PtrArg = PointerArgs[i].first;
Type *AgTy = cast<PointerType>(PtrArg->getType())->getElementType();
diff --git a/lib/Transforms/IPO/ConstantMerge.cpp b/lib/Transforms/IPO/ConstantMerge.cpp
index d8fae8a4b2..e2f012657f 100644
--- a/lib/Transforms/IPO/ConstantMerge.cpp
+++ b/lib/Transforms/IPO/ConstantMerge.cpp
@@ -23,7 +23,7 @@
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -50,7 +50,7 @@ namespace {
// alignment to a concrete value.
unsigned getAlignment(GlobalVariable *GV) const;
- const TargetData *TD;
+ const DataLayout *TD;
};
}
@@ -98,7 +98,7 @@ unsigned ConstantMerge::getAlignment(GlobalVariable *GV) const {
}
bool ConstantMerge::runOnModule(Module &M) {
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
// Find all the globals that are marked "used". These cannot be merged.
SmallPtrSet<const GlobalValue*, 8> UsedGlobals;
@@ -107,7 +107,7 @@ bool ConstantMerge::runOnModule(Module &M) {
// Map unique <constants, has-unknown-alignment> pairs to globals. We don't
// want to merge globals of unknown alignment with those of explicit
- // alignment. If we have TargetData, we always know the alignment.
+ // alignment. If we have DataLayout, we always know the alignment.
DenseMap<PointerIntPair<Constant*, 1, bool>, GlobalVariable*> CMap;
// Replacements - This vector contains a list of replacements to perform.
diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp
index c7429c5954..b107669b17 100644
--- a/lib/Transforms/IPO/DeadArgumentElimination.cpp
+++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp
@@ -21,7 +21,9 @@
#include "llvm/Transforms/IPO.h"
#include "llvm/CallingConv.h"
#include "llvm/Constant.h"
+#include "llvm/DebugInfo.h"
#include "llvm/DerivedTypes.h"
+#include "llvm/DIBuilder.h"
#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/LLVMContext.h"
@@ -30,6 +32,7 @@
#include "llvm/Support/CallSite.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
@@ -121,6 +124,15 @@ namespace {
typedef SmallVector<RetOrArg, 5> UseVector;
+ // Map each LLVM function to corresponding metadata with debug info. If
+ // the function is replaced with another one, we should patch the pointer
+ // to LLVM function in metadata.
+ // As the code generation for module is finished (and DIBuilder is
+ // finalized) we assume that subprogram descriptors won't be changed, and
+ // they are stored in map for short duration anyway.
+ typedef DenseMap<Function*, DISubprogram> FunctionDIMap;
+ FunctionDIMap FunctionDIs;
+
protected:
// DAH uses this to specify a different ID.
explicit DAE(char &ID) : ModulePass(ID) {}
@@ -141,6 +153,7 @@ namespace {
unsigned RetValNum = 0);
Liveness SurveyUses(const Value *V, UseVector &MaybeLiveUses);
+ void CollectFunctionDIs(Module &M);
void SurveyFunction(const Function &F);
void MarkValue(const RetOrArg &RA, Liveness L,
const UseVector &MaybeLiveUses);
@@ -180,6 +193,33 @@ INITIALIZE_PASS(DAH, "deadarghaX0r",
ModulePass *llvm::createDeadArgEliminationPass() { return new DAE(); }
ModulePass *llvm::createDeadArgHackingPass() { return new DAH(); }
+/// CollectFunctionDIs - Map each function in the module to its debug info
+/// descriptor.
+void DAE::CollectFunctionDIs(Module &M) {
+ FunctionDIs.clear();
+
+ for (Module::named_metadata_iterator I = M.named_metadata_begin(),
+ E = M.named_metadata_end(); I != E; ++I) {
+ NamedMDNode &NMD = *I;
+ for (unsigned MDIndex = 0, MDNum = NMD.getNumOperands();
+ MDIndex < MDNum; ++MDIndex) {
+ MDNode *Node = NMD.getOperand(MDIndex);
+ if (!DIDescriptor(Node).isCompileUnit())
+ continue;
+ DICompileUnit CU(Node);
+ const DIArray &SPs = CU.getSubprograms();
+ for (unsigned SPIndex = 0, SPNum = SPs.getNumElements();
+ SPIndex < SPNum; ++SPIndex) {
+ DISubprogram SP(SPs.getElement(SPIndex));
+ if (!SP.Verify())
+ continue;
+ if (Function *F = SP.getFunction())
+ FunctionDIs[F] = SP;
+ }
+ }
+ }
+}
+
/// DeleteDeadVarargs - If this is an function that takes a ... list, and if
/// llvm.vastart is never called, the varargs list is dead for the function.
bool DAE::DeleteDeadVarargs(Function &Fn) {
@@ -284,6 +324,11 @@ bool DAE::DeleteDeadVarargs(Function &Fn) {
I2->takeName(I);
}
+ // Patch the pointer to LLVM function in debug info descriptor.
+ FunctionDIMap::iterator DI = FunctionDIs.find(&Fn);
+ if (DI != FunctionDIs.end())
+ DI->second.replaceFunction(NF);
+
// Finally, nuke the old function.
Fn.eraseFromParent();
return true;
@@ -749,7 +794,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
}
}
- if (FnAttrs != Attribute::None)
+ if (FnAttrs.hasAttributes())
AttributesVec.push_back(AttributeWithIndex::get(~0, FnAttrs));
// Reconstruct the AttributesList based on the vector we constructed.
@@ -811,7 +856,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
AttributesVec.push_back(AttributeWithIndex::get(Args.size(), Attrs));
}
- if (FnAttrs != Attribute::None)
+ if (FnAttrs.hasAttributes())
AttributesVec.push_back(AttributeWithIndex::get(~0, FnAttrs));
// Reconstruct the AttributesList based on the vector we constructed.
@@ -952,6 +997,11 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
BB->getInstList().erase(RI);
}
+ // Patch the pointer to LLVM function in debug info descriptor.
+ FunctionDIMap::iterator DI = FunctionDIs.find(F);
+ if (DI != FunctionDIs.end())
+ DI->second.replaceFunction(NF);
+
// Now that the old function is dead, delete it.
F->eraseFromParent();
@@ -961,6 +1011,9 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
bool DAE::runOnModule(Module &M) {
bool Changed = false;
+ // Collect debug info descriptors for functions.
+ CollectFunctionDIs(M);
+
// First pass: Do a simple check to see if any functions can have their "..."
// removed. We can do this if they never call va_start. This loop cannot be
// fused with the next loop, because deleting a function invalidates
diff --git a/lib/Transforms/IPO/FunctionAttrs.cpp b/lib/Transforms/IPO/FunctionAttrs.cpp
index f3f6228433..e0deb43311 100644
--- a/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -276,8 +276,6 @@ namespace {
void tooManyUses() { Captured = true; }
- bool shouldExplore(Use *U) { return true; }
-
bool captured(Use *U) {
CallSite CS(U->getUser());
if (!CS.getInstruction()) { Captured = true; return true; }
@@ -520,7 +518,7 @@ bool FunctionAttrs::IsFunctionMallocLike(Function *F,
case Instruction::Call:
case Instruction::Invoke: {
CallSite CS(RVI);
- if (CS.paramHasAttr(0, Attribute::NoAlias))
+ if (CS.paramHasAttr(0, Attributes::NoAlias))
break;
if (CS.getCalledFunction() &&
SCCNodes.count(CS.getCalledFunction()))
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp
index b1ba6be5ff..e8e54ec9ae 100644
--- a/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/lib/Transforms/IPO/GlobalOpt.cpp
@@ -25,7 +25,7 @@
#include "llvm/Pass.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/MemoryBuiltins.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/Debug.h"
@@ -83,7 +83,7 @@ namespace {
const GlobalStatus &GS);
bool OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn);
- TargetData *TD;
+ DataLayout *TD;
TargetLibraryInfo *TLI;
};
}
@@ -464,7 +464,7 @@ static bool CleanupPointerRootUsers(GlobalVariable *GV,
/// quick scan over the use list to clean up the easy and obvious cruft. This
/// returns true if it made a change.
static bool CleanupConstantGlobalUsers(Value *V, Constant *Init,
- TargetData *TD, TargetLibraryInfo *TLI) {
+ DataLayout *TD, TargetLibraryInfo *TLI) {
bool Changed = false;
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;) {
User *U = *UI++;
@@ -656,7 +656,7 @@ static bool GlobalUsersSafeToSRA(GlobalValue *GV) {
/// behavior of the program in a more fine-grained way. We have determined that
/// this transformation is safe already. We return the first global variable we
/// insert so that the caller can reprocess it.
-static GlobalVariable *SRAGlobal(GlobalVariable *GV, const TargetData &TD) {
+static GlobalVariable *SRAGlobal(GlobalVariable *GV, const DataLayout &TD) {
// Make sure this global only has simple uses that we can SRA.
if (!GlobalUsersSafeToSRA(GV))
return 0;
@@ -932,7 +932,7 @@ static bool OptimizeAwayTrappingUsesOfValue(Value *V, Constant *NewV) {
/// if the loaded value is dynamically null, then we know that they cannot be
/// reachable with a null optimize away the load.
static bool OptimizeAwayTrappingUsesOfLoads(GlobalVariable *GV, Constant *LV,
- TargetData *TD,
+ DataLayout *TD,
TargetLibraryInfo *TLI) {
bool Changed = false;
@@ -996,7 +996,7 @@ static bool OptimizeAwayTrappingUsesOfLoads(GlobalVariable *GV, Constant *LV,
/// ConstantPropUsersOf - Walk the use list of V, constant folding all of the
/// instructions that are foldable.
static void ConstantPropUsersOf(Value *V,
- TargetData *TD, TargetLibraryInfo *TLI) {
+ DataLayout *TD, TargetLibraryInfo *TLI) {
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; )
if (Instruction *I = dyn_cast<Instruction>(*UI++))
if (Constant *NewC = ConstantFoldInstruction(I, TD, TLI)) {
@@ -1019,7 +1019,7 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
CallInst *CI,
Type *AllocTy,
ConstantInt *NElements,
- TargetData *TD,
+ DataLayout *TD,
TargetLibraryInfo *TLI) {
DEBUG(errs() << "PROMOTING GLOBAL: " << *GV << " CALL = " << *CI << '\n');
@@ -1468,7 +1468,7 @@ static void RewriteUsesOfLoadForHeapSRoA(LoadInst *Load,
/// PerformHeapAllocSRoA - CI is an allocation of an array of structures. Break
/// it up into multiple allocations of arrays of the fields.
static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, CallInst *CI,
- Value *NElems, TargetData *TD,
+ Value *NElems, DataLayout *TD,
const TargetLibraryInfo *TLI) {
DEBUG(dbgs() << "SROA HEAP ALLOC: " << *GV << " MALLOC = " << *CI << '\n');
Type *MAT = getMallocAllocatedType(CI, TLI);
@@ -1660,7 +1660,7 @@ static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV,
Type *AllocTy,
AtomicOrdering Ordering,
Module::global_iterator &GVI,
- TargetData *TD,
+ DataLayout *TD,
TargetLibraryInfo *TLI) {
if (!TD)
return false;
@@ -1759,7 +1759,7 @@ static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV,
static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal,
AtomicOrdering Ordering,
Module::global_iterator &GVI,
- TargetData *TD, TargetLibraryInfo *TLI) {
+ DataLayout *TD, TargetLibraryInfo *TLI) {
// Ignore no-op GEPs and bitcasts.
StoredOnceVal = StoredOnceVal->stripPointerCasts();
@@ -2002,7 +2002,7 @@ bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV,
++NumMarked;
return true;
} else if (!GV->getInitializer()->getType()->isSingleValueType()) {
- if (TargetData *TD = getAnalysisIfAvailable<TargetData>())
+ if (DataLayout *TD = getAnalysisIfAvailable<DataLayout>())
if (GlobalVariable *FirstNewGV = SRAGlobal(GV, *TD)) {
GVI = FirstNewGV; // Don't skip the newly produced globals!
return true;
@@ -2063,7 +2063,7 @@ static void ChangeCalleesToFastCall(Function *F) {
static AttrListPtr StripNest(const AttrListPtr &Attrs) {
for (unsigned i = 0, e = Attrs.getNumSlots(); i != e; ++i) {
- if ((Attrs.getSlot(i).Attrs & Attribute::Nest) == 0)
+ if (!Attrs.getSlot(i).Attrs.hasAttribute(Attributes::Nest))
continue;
// There can be only one.
@@ -2256,7 +2256,7 @@ static GlobalVariable *InstallGlobalCtors(GlobalVariable *GCL,
static inline bool
isSimpleEnoughValueToCommit(Constant *C,
SmallPtrSet<Constant*, 8> &SimpleConstants,
- const TargetData *TD);
+ const DataLayout *TD);
/// isSimpleEnoughValueToCommit - Return true if the specified constant can be
@@ -2269,7 +2269,7 @@ isSimpleEnoughValueToCommit(Constant *C,
/// time.
static bool isSimpleEnoughValueToCommitHelper(Constant *C,
SmallPtrSet<Constant*, 8> &SimpleConstants,
- const TargetData *TD) {
+ const DataLayout *TD) {
// Simple integer, undef, constant aggregate zero, global addresses, etc are
// all supported.
if (C->getNumOperands() == 0 || isa<BlockAddress>(C) ||
@@ -2324,7 +2324,7 @@ static bool isSimpleEnoughValueToCommitHelper(Constant *C,
static inline bool
isSimpleEnoughValueToCommit(Constant *C,
SmallPtrSet<Constant*, 8> &SimpleConstants,
- const TargetData *TD) {
+ const DataLayout *TD) {
// If we already checked this constant, we win.
if (!SimpleConstants.insert(C)) return true;
// Check the constant.
@@ -2455,7 +2455,7 @@ namespace {
/// Once an evaluation call fails, the evaluation object should not be reused.
class Evaluator {
public:
- Evaluator(const TargetData *TD, const TargetLibraryInfo *TLI)
+ Evaluator(const DataLayout *TD, const TargetLibraryInfo *TLI)
: TD(TD), TLI(TLI) {
ValueStack.push_back(new DenseMap<Value*, Constant*>);
}
@@ -2536,7 +2536,7 @@ private:
/// simple enough to live in a static initializer of a global.
SmallPtrSet<Constant*, 8> SimpleConstants;
- const TargetData *TD;
+ const DataLayout *TD;
const TargetLibraryInfo *TLI;
};
@@ -2874,7 +2874,7 @@ bool Evaluator::EvaluateFunction(Function *F, Constant *&RetVal,
/// EvaluateStaticConstructor - Evaluate static constructors in the function, if
/// we can. Return true if we can, false otherwise.
-static bool EvaluateStaticConstructor(Function *F, const TargetData *TD,
+static bool EvaluateStaticConstructor(Function *F, const DataLayout *TD,
const TargetLibraryInfo *TLI) {
// Call the function.
Evaluator Eval(TD, TLI);
@@ -3115,7 +3115,7 @@ bool GlobalOpt::OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn) {
bool GlobalOpt::runOnModule(Module &M) {
bool Changed = false;
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
TLI = &getAnalysis<TargetLibraryInfo>();
// Try to find the llvm.globalctors list.
diff --git a/lib/Transforms/IPO/InlineAlways.cpp b/lib/Transforms/IPO/InlineAlways.cpp
index 42f0991360..b1c36c15db 100644
--- a/lib/Transforms/IPO/InlineAlways.cpp
+++ b/lib/Transforms/IPO/InlineAlways.cpp
@@ -23,7 +23,7 @@
#include "llvm/Support/CallSite.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/InlinerPass.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/ADT/SmallPtrSet.h"
using namespace llvm;
@@ -65,7 +65,7 @@ Pass *llvm::createAlwaysInlinerPass(bool InsertLifetime) {
/// \brief Minimal filter to detect invalid constructs for inlining.
static bool isInlineViable(Function &F) {
- bool ReturnsTwice = F.getFnAttributes().hasReturnsTwiceAttr();
+ bool ReturnsTwice =F.getFnAttributes().hasAttribute(Attributes::ReturnsTwice);
for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) {
// Disallow inlining of functions which contain an indirect branch.
if (isa<IndirectBrInst>(BI->getTerminator()))
@@ -114,7 +114,7 @@ InlineCost AlwaysInliner::getInlineCost(CallSite CS) {
if (Callee->isDeclaration()) return InlineCost::getNever();
// Return never for anything not marked as always inline.
- if (!Callee->getFnAttributes().hasAlwaysInlineAttr())
+ if (!Callee->getFnAttributes().hasAttribute(Attributes::AlwaysInline))
return InlineCost::getNever();
// Do some minimal analysis to preclude non-viable functions.
diff --git a/lib/Transforms/IPO/InlineSimple.cpp b/lib/Transforms/IPO/InlineSimple.cpp
index 50038d8116..bf0b1f91a2 100644
--- a/lib/Transforms/IPO/InlineSimple.cpp
+++ b/lib/Transforms/IPO/InlineSimple.cpp
@@ -22,7 +22,7 @@
#include "llvm/Support/CallSite.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/InlinerPass.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
using namespace llvm;
@@ -62,7 +62,7 @@ Pass *llvm::createFunctionInliningPass(int Threshold) {
// doInitialization - Initializes the vector of functions that have been
// annotated with the noinline attribute.
bool SimpleInliner::doInitialization(CallGraph &CG) {
- CA.setTargetData(getAnalysisIfAvailable<TargetData>());
+ CA.setDataLayout(getAnalysisIfAvailable<DataLayout>());
return false;
}
diff --git a/lib/Transforms/IPO/Inliner.cpp b/lib/Transforms/IPO/Inliner.cpp
index 7932b40bdc..876afd19f1 100644
--- a/lib/Transforms/IPO/Inliner.cpp
+++ b/lib/Transforms/IPO/Inliner.cpp
@@ -19,7 +19,7 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/InlineCost.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/IPO/InlinerPass.h"
#include "llvm/Transforms/Utils/Cloning.h"
@@ -93,10 +93,10 @@ static bool InlineCallIfPossible(CallSite CS, InlineFunctionInfo &IFI,
// If the inlined function had a higher stack protection level than the
// calling function, then bump up the caller's stack protection level.
- if (Callee->getFnAttributes().hasStackProtectReqAttr())
+ if (Callee->getFnAttributes().hasAttribute(Attributes::StackProtectReq))
Caller->addFnAttr(Attribute::StackProtectReq);
- else if (Callee->getFnAttributes().hasStackProtectAttr() &&
- !Caller->getFnAttributes().hasStackProtectReqAttr())
+ else if (Callee->getFnAttributes().hasAttribute(Attributes::StackProtect) &&
+ !Caller->getFnAttributes().hasAttribute(Attributes::StackProtectReq))
Caller->addFnAttr(Attribute::StackProtect);
// Look at all of the allocas that we inlined through this call site. If we
@@ -209,7 +209,7 @@ unsigned Inliner::getInlineThreshold(CallSite CS) const {
// would decrease the threshold.
Function *Caller = CS.getCaller();
bool OptSize = Caller && !Caller->isDeclaration() &&
- Caller->getFnAttributes().hasOptimizeForSizeAttr();
+ Caller->getFnAttributes().hasAttribute(Attributes::OptimizeForSize);
if (!(InlineLimit.getNumOccurrences() > 0) && OptSize &&
OptSizeThreshold < thres)
thres = OptSizeThreshold;
@@ -217,7 +217,7 @@ unsigned Inliner::getInlineThreshold(CallSite CS) const {
// Listen to the inlinehint attribute when it would increase the threshold.
Function *Callee = CS.getCalledFunction();
bool InlineHint = Callee && !Callee->isDeclaration() &&
- Callee->getFnAttributes().hasInlineHintAttr();
+ Callee->getFnAttributes().hasAttribute(Attributes::InlineHint);
if (InlineHint && HintThreshold > thres)
thres = HintThreshold;
@@ -340,7 +340,7 @@ static bool InlineHistoryIncludes(Function *F, int InlineHistoryID,
bool Inliner::runOnSCC(CallGraphSCC &SCC) {
CallGraph &CG = getAnalysis<CallGraph>();
- const TargetData *TD = getAnalysisIfAvailable<TargetData>();
+ const DataLayout *TD = getAnalysisIfAvailable<DataLayout>();
const TargetLibraryInfo *TLI = getAnalysisIfAvailable<TargetLibraryInfo>();
SmallPtrSet<Function*, 8> SCCFunctions;
@@ -533,7 +533,8 @@ bool Inliner::removeDeadFunctions(CallGraph &CG, bool AlwaysInlineOnly) {
// Handle the case when this function is called and we only want to care
// about always-inline functions. This is a bit of a hack to share code
// between here and the InlineAlways pass.
- if (AlwaysInlineOnly && !F->getFnAttributes().hasAlwaysInlineAttr())
+ if (AlwaysInlineOnly &&
+ !F->getFnAttributes().hasAttribute(Attributes::AlwaysInline))
continue;
// If the only remaining users of the function are dead constants, remove
diff --git a/lib/Transforms/IPO/MergeFunctions.cpp b/lib/Transforms/IPO/MergeFunctions.cpp
index 9f70f668a8..44283ddce7 100644
--- a/lib/Transforms/IPO/MergeFunctions.cpp
+++ b/lib/Transforms/IPO/MergeFunctions.cpp
@@ -63,7 +63,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include <vector>
using namespace llvm;
@@ -92,19 +92,19 @@ static unsigned profileFunction(const Function *F) {
namespace {
/// ComparableFunction - A struct that pairs together functions with a
-/// TargetData so that we can keep them together as elements in the DenseSet.
+/// DataLayout so that we can keep them together as elements in the DenseSet.
class ComparableFunction {
public:
static const ComparableFunction EmptyKey;
static const ComparableFunction TombstoneKey;
- static TargetData * const LookupOnly;
+ static DataLayout * const LookupOnly;
- ComparableFunction(Function *Func, TargetData *TD)
+ ComparableFunction(Function *Func, DataLayout *TD)
: Func(Func), Hash(profileFunction(Func)), TD(TD) {}
Function *getFunc() const { return Func; }
unsigned getHash() const { return Hash; }
- TargetData *getTD() const { return TD; }
+ DataLayout *getTD() const { return TD; }
// Drops AssertingVH reference to the function. Outside of debug mode, this
// does nothing.
@@ -120,13 +120,13 @@ private:
AssertingVH<Function> Func;
unsigned Hash;
- TargetData *TD;
+ DataLayout *TD;
};
const ComparableFunction ComparableFunction::EmptyKey = ComparableFunction(0);
const ComparableFunction ComparableFunction::TombstoneKey =
ComparableFunction(1);
-TargetData *const ComparableFunction::LookupOnly = (TargetData*)(-1);
+DataLayout *const ComparableFunction::LookupOnly = (DataLayout*)(-1);
}
@@ -150,12 +150,12 @@ namespace llvm {
namespace {
/// FunctionComparator - Compares two functions to determine whether or not
-/// they will generate machine code with the same behaviour. TargetData is
+/// they will generate machine code with the same behaviour. DataLayout is
/// used if available. The comparator always fails conservatively (erring on the
/// side of claiming that two functions are different).
class FunctionComparator {
public:
- FunctionComparator(const TargetData *TD, const Function *F1,
+ FunctionComparator(const DataLayout *TD, const Function *F1,
const Function *F2)
: F1(F1), F2(F2), TD(TD) {}
@@ -190,7 +190,7 @@ private:
// The two functions undergoing comparison.
const Function *F1, *F2;
- const TargetData *TD;
+ const DataLayout *TD;
DenseMap<const Value *, const Value *> id_map;
DenseSet<const Value *> seen_values;
@@ -591,8 +591,8 @@ private:
/// to modify it.
FnSetType FnSet;
- /// TargetData for more accurate GEP comparisons. May be NULL.
- TargetData *TD;
+ /// DataLayout for more accurate GEP comparisons. May be NULL.
+ DataLayout *TD;
/// Whether or not the target supports global aliases.
bool HasGlobalAliases;
@@ -609,7 +609,7 @@ ModulePass *llvm::createMergeFunctionsPass() {
bool MergeFunctions::runOnModule(Module &M) {
bool Changed = false;
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
if (!I->isDeclaration() && !I->hasAvailableExternallyLinkage())
diff --git a/lib/Transforms/IPO/PassManagerBuilder.cpp b/lib/Transforms/IPO/PassManagerBuilder.cpp
index 9e328b9ac9..a2862022a3 100644
--- a/lib/Transforms/IPO/PassManagerBuilder.cpp
+++ b/lib/Transforms/IPO/PassManagerBuilder.cpp
@@ -41,7 +41,7 @@ UseGVNAfterVectorization("use-gvn-after-vectorization",
cl::desc("Run GVN instead of Early CSE after vectorization passes"));
static cl::opt<bool> UseNewSROA("use-new-sroa",
- cl::init(false), cl::Hidden,
+ cl::init(true), cl::Hidden,
cl::desc("Enable the new, experimental SROA pass"));
PassManagerBuilder::PassManagerBuilder() {
diff --git a/lib/Transforms/IPO/PruneEH.cpp b/lib/Transforms/IPO/PruneEH.cpp
index c8cc8fd193..3e598abfcf 100644
--- a/lib/Transforms/IPO/PruneEH.cpp
+++ b/lib/Transforms/IPO/PruneEH.cpp
@@ -137,16 +137,16 @@ bool PruneEH::runOnSCC(CallGraphSCC &SCC) {
// If the SCC doesn't unwind or doesn't throw, note this fact.
if (!SCCMightUnwind || !SCCMightReturn)
for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
- Attributes NewAttributes = Attribute::None;
+ Attributes::Builder NewAttributes;
if (!SCCMightUnwind)
- NewAttributes |= Attribute::NoUnwind;
+ NewAttributes.addAttribute(Attributes::NoUnwind);
if (!SCCMightReturn)
- NewAttributes |= Attribute::NoReturn;
+ NewAttributes.addAttribute(Attributes::NoReturn);
Function *F = (*I)->getFunction();
const AttrListPtr &PAL = F->getAttributes();
- const AttrListPtr &NPAL = PAL.addAttr(~0, NewAttributes);
+ const AttrListPtr &NPAL = PAL.addAttr(~0, Attributes::get(NewAttributes));
if (PAL != NPAL) {
MadeChange = true;
F->setAttributes(NPAL);
diff --git a/lib/Transforms/InstCombine/InstCombine.h b/lib/Transforms/InstCombine/InstCombine.h
index 0d5ef904ee..325bb20fbe 100644
--- a/lib/Transforms/InstCombine/InstCombine.h
+++ b/lib/Transforms/InstCombine/InstCombine.h
@@ -21,7 +21,7 @@
namespace llvm {
class CallSite;
- class TargetData;
+ class DataLayout;
class TargetLibraryInfo;
class DbgDeclareInst;
class MemIntrinsic;
@@ -71,7 +71,7 @@ public:
class LLVM_LIBRARY_VISIBILITY InstCombiner
: public FunctionPass,
public InstVisitor<InstCombiner, Instruction*> {
- TargetData *TD;
+ DataLayout *TD;
TargetLibraryInfo *TLI;
bool MadeIRChange;
public:
@@ -95,7 +95,7 @@ public:
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
- TargetData *getTargetData() const { return TD; }
+ DataLayout *getDataLayout() const { return TD; }
TargetLibraryInfo *getTargetLibraryInfo() const { return TLI; }
@@ -218,7 +218,7 @@ private:
Type *Ty);
Instruction *visitCallSite(CallSite CS);
- Instruction *tryOptimizeCall(CallInst *CI, const TargetData *TD);
+ Instruction *tryOptimizeCall(CallInst *CI, const DataLayout *TD);
bool transformConstExprCastCall(CallSite CS);
Instruction *transformCallThroughTrampoline(CallSite CS,
IntrinsicInst *Tramp);
diff --git a/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 99b62f8d05..d8257e64d8 100644
--- a/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -13,7 +13,7 @@
#include "InstCombine.h"
#include "llvm/Analysis/InstructionSimplify.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/PatternMatch.h"
using namespace llvm;
diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp
index ac30dcdcbf..b3aa4daaa8 100644
--- a/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -13,7 +13,7 @@
#include "InstCombine.h"
#include "llvm/Support/CallSite.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Transforms/Utils/BuildLibCalls.h"
#include "llvm/Transforms/Utils/Local.h"
@@ -754,7 +754,7 @@ Instruction *InstCombiner::visitInvokeInst(InvokeInst &II) {
/// passed through the varargs area, we can eliminate the use of the cast.
static bool isSafeToEliminateVarargsCast(const CallSite CS,
const CastInst * const CI,
- const TargetData * const TD,
+ const DataLayout * const TD,
const int ix) {
if (!CI->isLosslessCast())
return false;
@@ -812,7 +812,7 @@ public:
// Currently we're only working with the checking functions, memcpy_chk,
// mempcpy_chk, memmove_chk, memset_chk, strcpy_chk, stpcpy_chk, strncpy_chk,
// strcat_chk and strncat_chk.
-Instruction *InstCombiner::tryOptimizeCall(CallInst *CI, const TargetData *TD) {
+Instruction *InstCombiner::tryOptimizeCall(CallInst *CI, const DataLayout *TD) {
if (CI->getCalledFunction() == 0) return 0;
InstCombineFortifiedLibCalls Simplifier(this);
@@ -984,7 +984,7 @@ Instruction *InstCombiner::visitCallSite(CallSite CS) {
Changed = true;
}
- // Try to optimize the call if possible, we require TargetData for most of
+ // Try to optimize the call if possible, we require DataLayout for most of
// this. None of these calls are seen as possibly dead so go ahead and
// delete the instruction now.
if (CallInst *CI = dyn_cast<CallInst>(CS.getInstruction())) {
@@ -1036,8 +1036,8 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
return false; // Cannot transform this return value.
if (!CallerPAL.isEmpty() && !Caller->use_empty()) {
- Attributes RAttrs = CallerPAL.getRetAttributes();
- if (RAttrs & Attributes::typeIncompatible(NewRetTy))
+ Attributes::Builder RAttrs = CallerPAL.getRetAttributes();
+ if (RAttrs.hasAttributes(Attributes::typeIncompatible(NewRetTy)))
return false; // Attribute not compatible with transformed value.
}
@@ -1072,7 +1072,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
// If the parameter is passed as a byval argument, then we have to have a
// sized type and the sized type has to have the same size as the old type.
- if (ParamTy != ActTy && (Attrs & Attribute::ByVal)) {
+ if (ParamTy != ActTy && Attrs.hasAttribute(Attributes::ByVal)) {
PointerType *ParamPTy = dyn_cast<PointerType>(ParamTy);
if (ParamPTy == 0 || !ParamPTy->getElementType()->isSized() || TD == 0)
return false;
@@ -1124,7 +1124,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
if (CallerPAL.getSlot(i - 1).Index <= FT->getNumParams())
break;
Attributes PAttrs = CallerPAL.getSlot(i - 1).Attrs;
- if (PAttrs & Attribute::VarArgsIncompatible)
+ if (PAttrs.hasIncompatibleWithVarArgsAttrs())
return false;
}
@@ -1137,15 +1137,15 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
attrVec.reserve(NumCommonArgs);
// Get any return attributes.
- Attributes RAttrs = CallerPAL.getRetAttributes();
+ Attributes::Builder RAttrs = CallerPAL.getRetAttributes();
// If the return value is not being used, the type may not be compatible
// with the existing attributes. Wipe out any problematic attributes.
- RAttrs &= ~Attributes::typeIncompatible(NewRetTy);
+ RAttrs.removeAttributes(Attributes::typeIncompatible(NewRetTy));
// Add the new return attributes.
- if (RAttrs)
- attrVec.push_back(AttributeWithIndex::get(0, RAttrs));
+ if (RAttrs.hasAttributes())
+ attrVec.push_back(AttributeWithIndex::get(0, Attributes::get(RAttrs)));
AI = CS.arg_begin();
for (unsigned i = 0; i != NumCommonArgs; ++i, ++AI) {
@@ -1265,8 +1265,9 @@ InstCombiner::transformCallThroughTrampoline(CallSite CS,
// If the call already has the 'nest' attribute somewhere then give up -
// otherwise 'nest' would occur twice after splicing in the chain.
- if (Attrs.hasAttrSomewhere(Attribute::Nest))
- return 0;
+ for (unsigned I = 0, E = Attrs.getNumAttrs(); I != E; ++I)
+ if (Attrs.getAttributesAtIndex(I).hasAttribute(Attributes::Nest))
+ return 0;
assert(Tramp &&
"transformCallThroughTrampoline called with incorrect CallSite.");
@@ -1279,12 +1280,12 @@ InstCombiner::transformCallThroughTrampoline(CallSite CS,
if (!NestAttrs.isEmpty()) {
unsigned NestIdx = 1;
Type *NestTy = 0;
- Attributes NestAttr = Attribute::None;
+ Attributes NestAttr;
// Look for a parameter marked with the 'nest' attribute.
for (FunctionType::param_iterator I = NestFTy->param_begin(),
E = NestFTy->param_end(); I != E; ++NestIdx, ++I)
- if (NestAttrs.paramHasAttr(NestIdx, Attribute::Nest)) {
+ if (NestAttrs.getParamAttributes(NestIdx).hasAttribute(Attributes::Nest)){
// Record the parameter type and any other attributes.
NestTy = *I;
NestAttr = NestAttrs.getParamAttributes(NestIdx);
diff --git a/lib/Transforms/InstCombine/InstCombineCasts.cpp b/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 555b4428d2..b59210a9df 100644
--- a/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -13,7 +13,7 @@
#include "InstCombine.h"
#include "llvm/Analysis/ConstantFolding.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Support/PatternMatch.h"
using namespace llvm;
@@ -78,7 +78,7 @@ static Value *DecomposeSimpleLinearExpr(Value *Val, unsigned &Scale,
/// try to eliminate the cast by moving the type information into the alloc.
Instruction *InstCombiner::PromoteCastOfAllocation(BitCastInst &CI,
AllocaInst &AI) {
- // This requires TargetData to get the alloca alignment and size information.
+ // This requires DataLayout to get the alloca alignment and size information.
if (!TD) return 0;
PointerType *PTy = cast<PointerType>(CI.getType());
@@ -229,7 +229,7 @@ isEliminableCastPair(
const CastInst *CI, ///< The first cast instruction
unsigned opcode, ///< The opcode of the second cast instruction
Type *DstTy, ///< The target type for the second cast instruction
- TargetData *TD ///< The target data for pointer size
+ DataLayout *TD ///< The target data for pointer size
) {
Type *SrcTy = CI->getOperand(0)->getType(); // A from above
diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp
index c3fc18c300..4d5ffddc4c 100644
--- a/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -16,7 +16,7 @@
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/MemoryBuiltins.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Support/ConstantRange.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
@@ -474,7 +474,7 @@ FoldCmpLoadFromIndexedGlobal(GetElementPtrInst *GEP, GlobalVariable *GV,
/// If we can't emit an optimized form for this expression, this returns null.
///
static Value *EvaluateGEPOffsetExpression(User *GEP, InstCombiner &IC) {
- TargetData &TD = *IC.getTargetData();
+ DataLayout &TD = *IC.getDataLayout();
gep_type_iterator GTI = gep_type_begin(GEP);
// Check to see if this gep only has a single variable index. If so, and if
diff --git a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
index a446e427e5..4ab5b6e4a0 100644
--- a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -14,7 +14,7 @@
#include "InstCombine.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Analysis/Loads.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/ADT/Statistic.h"
@@ -152,7 +152,7 @@ isOnlyCopiedFromConstantGlobal(AllocaInst *AI,
/// getPointeeAlignment - Compute the minimum alignment of the value pointed
/// to by the given pointer.
-static unsigned getPointeeAlignment(Value *V, const TargetData &TD) {
+static unsigned getPointeeAlignment(Value *V, const DataLayout &TD) {
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
if (CE->getOpcode() == Instruction::BitCast ||
(CE->getOpcode() == Instruction::GetElementPtr &&
@@ -297,7 +297,7 @@ Instruction *InstCombiner::visitAllocaInst(AllocaInst &AI) {
/// InstCombineLoadCast - Fold 'load (cast P)' -> cast (load P)' when possible.
static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI,
- const TargetData *TD) {
+ const DataLayout *TD) {
User *CI = cast<User>(LI.getOperand(0));
Value *CastOp = CI->getOperand(0);
@@ -327,14 +327,14 @@ static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI,
SrcPTy = SrcTy->getElementType();
}
- if (IC.getTargetData() &&
+ if (IC.getDataLayout() &&
(SrcPTy->isIntegerTy() || SrcPTy->isPointerTy() ||
SrcPTy->isVectorTy()) &&
// Do not allow turning this into a load of an integer, which is then
// casted to a pointer, this pessimizes pointer analysis a lot.
(SrcPTy->isPointerTy() == LI.getType()->isPointerTy()) &&
- IC.getTargetData()->getTypeSizeInBits(SrcPTy) ==
- IC.getTargetData()->getTypeSizeInBits(DestPTy)) {
+ IC.getDataLayout()->getTypeSizeInBits(SrcPTy) ==
+ IC.getDataLayout()->getTypeSizeInBits(DestPTy)) {
// Okay, we are casting from one integer or pointer type to another of
// the same size. Instead of casting the pointer before the load, cast
@@ -512,11 +512,11 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
// If the pointers point into different address spaces or if they point to
// values with different sizes, we can't do the transformation.
- if (!IC.getTargetData() ||
+ if (!IC.getDataLayout() ||
SrcTy->getAddressSpace() !=
cast<PointerType>(CI->getType())->getAddressSpace() ||
- IC.getTargetData()->getTypeSizeInBits(SrcPTy) !=
- IC.getTargetData()->getTypeSizeInBits(DestPTy))
+ IC.getDataLayout()->getTypeSizeInBits(SrcPTy) !=
+ IC.getDataLayout()->getTypeSizeInBits(DestPTy))
return 0;
// Okay, we are casting from one integer or pointer type to another of
diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 3361a1e7fb..cefe45ec86 100644
--- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -37,7 +37,7 @@ static Value *simplifyValueKnownNonZero(Value *V, InstCombiner &IC) {
if (match(V, m_LShr(m_OneUse(m_Shl(m_Value(PowerOf2), m_Value(A))),
m_Value(B))) &&
// The "1" can be any value known to be a power of 2.
- isPowerOfTwo(PowerOf2, IC.getTargetData())) {
+ isPowerOfTwo(PowerOf2, IC.getDataLayout())) {
A = IC.Builder->CreateSub(A, B);
return IC.Builder->CreateShl(PowerOf2, A);
}
@@ -46,7 +46,7 @@ static Value *simplifyValueKnownNonZero(Value *V, InstCombiner &IC) {
// inexact. Similarly for <<.
if (BinaryOperator *I = dyn_cast<BinaryOperator>(V))
if (I->isLogicalShift() &&
- isPowerOfTwo(I->getOperand(0), IC.getTargetData())) {
+ isPowerOfTwo(I->getOperand(0), IC.getDataLayout())) {
// We know that this is an exact/nuw shift and that the input is a
// non-zero context as well.
if (Value *V2 = simplifyValueKnownNonZero(I->getOperand(0), IC)) {
diff --git a/lib/Transforms/InstCombine/InstCombinePHI.cpp b/lib/Transforms/InstCombine/InstCombinePHI.cpp
index 664546c165..de9c77e600 100644
--- a/lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ b/lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -13,7 +13,7 @@
#include "InstCombine.h"
#include "llvm/Analysis/InstructionSimplify.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/STLExtras.h"
using namespace llvm;
diff --git a/lib/Transforms/InstCombine/InstCombineSelect.cpp b/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 0ba7340e64..ecce242a81 100644
--- a/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -287,7 +287,7 @@ Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, Value *TrueVal,
/// SimplifyWithOpReplaced - See if V simplifies when its operand Op is
/// replaced with RepOp.
static Value *SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
- const TargetData *TD,
+ const DataLayout *TD,
const TargetLibraryInfo *TLI) {
// Trivial replacement.
if (V == Op)
diff --git a/lib/Transforms/InstCombine/InstCombineShifts.cpp b/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 4bb2403299..57021f1bef 100644
--- a/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -190,7 +190,7 @@ static Value *GetShiftedValue(Value *V, unsigned NumBits, bool isLeftShift,
V = IC.Builder->CreateLShr(C, NumBits);
// If we got a constantexpr back, try to simplify it with TD info.
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
- V = ConstantFoldConstantExpression(CE, IC.getTargetData(),
+ V = ConstantFoldConstantExpression(CE, IC.getDataLayout(),
IC.getTargetLibraryInfo());
return V;
}
diff --git a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 54be8ed3fa..602b203371 100644
--- a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -14,7 +14,7 @@
#include "InstCombine.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/IntrinsicInst.h"
using namespace llvm;
diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp
index ff758c40af..edfc060888 100644
--- a/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -40,7 +40,7 @@
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/MemoryBuiltins.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Support/CFG.h"
@@ -88,7 +88,7 @@ void InstCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
Value *InstCombiner::EmitGEPOffset(User *GEP) {
- return llvm::EmitGEPOffset(Builder, *getTargetData(), GEP);
+ return llvm::EmitGEPOffset(Builder, *getDataLayout(), GEP);
}
/// ShouldChangeType - Return true if it is desirable to convert a computation
@@ -1854,7 +1854,7 @@ static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock) {
static bool AddReachableCodeToWorklist(BasicBlock *BB,
SmallPtrSet<BasicBlock*, 64> &Visited,
InstCombiner &IC,
- const TargetData *TD,
+ const DataLayout *TD,
const TargetLibraryInfo *TLI) {
bool MadeIRChange = false;
SmallVector<BasicBlock*, 256> Worklist;
@@ -2120,7 +2120,7 @@ bool InstCombiner::DoOneIteration(Function &F, unsigned Iteration) {
bool InstCombiner::runOnFunction(Function &F) {
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
TLI = &getAnalysis<TargetLibraryInfo>();
/// Builder - This is an IRBuilder that automatically inserts new
diff --git a/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 1b102bd243..10ab9cb603 100644
--- a/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -35,7 +35,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
@@ -207,7 +207,7 @@ struct AddressSanitizer : public ModulePass {
bool HasDynamicInitializer(GlobalVariable *G);
LLVMContext *C;
- TargetData *TD;
+ DataLayout *TD;
uint64_t MappingOffset;
int MappingScale;
size_t RedzoneSize;
@@ -736,7 +736,7 @@ bool AddressSanitizer::insertGlobalRedzones(Module &M) {
// virtual
bool AddressSanitizer::runOnModule(Module &M) {
// Initialize the private fields. No one has accessed them before.
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
if (!TD)
return false;
BL.reset(new BlackList(ClBlackListFile));
@@ -854,12 +854,14 @@ bool AddressSanitizer::handleFunction(Module &M, Function &F) {
// If needed, insert __asan_init before checking for AddressSafety attr.
maybeInsertAsanInitAtFunctionEntry(F);
- if (!F.getFnAttributes().hasAddressSafetyAttr()) return false;
+ if (!F.getFnAttributes().hasAttribute(Attributes::AddressSafety))
+ return false;
if (!ClDebugFunc.empty() && ClDebugFunc != F.getName())
return false;
- // We want to instrument every address only once per basic block
- // (unless there are calls between uses).
+
+ // We want to instrument every address only once per basic block (unless there
+ // are calls between uses).
SmallSet<Value*, 16> TempsToInstrument;
SmallVector<Instruction*, 16> ToInstrument;
SmallVector<Instruction*, 8> NoReturnCalls;
diff --git a/lib/Transforms/Instrumentation/BoundsChecking.cpp b/lib/Transforms/Instrumentation/BoundsChecking.cpp
index 642908120b..976b963046 100644
--- a/lib/Transforms/Instrumentation/BoundsChecking.cpp
+++ b/lib/Transforms/Instrumentation/BoundsChecking.cpp
@@ -23,7 +23,7 @@
#include "llvm/Support/InstIterator.h"
#include "llvm/Support/TargetFolder.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/Instrumentation.h"
using namespace llvm;
@@ -48,12 +48,12 @@ namespace {
virtual bool runOnFunction(Function &F);
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<TargetData>();
+ AU.addRequired<DataLayout>();
AU.addRequired<TargetLibraryInfo>();
}
private:
- const TargetData *TD;
+ const DataLayout *TD;
const TargetLibraryInfo *TLI;
ObjectSizeOffsetEvaluator *ObjSizeEval;
BuilderTy *Builder;
@@ -168,7 +168,7 @@ bool BoundsChecking::instrument(Value *Ptr, Value *InstVal) {
}
bool BoundsChecking::runOnFunction(Function &F) {
- TD = &getAnalysis<TargetData>();
+ TD = &getAnalysis<DataLayout>();
TLI = &getAnalysis<TargetLibraryInfo>();
TrapBB = 0;
diff --git a/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/lib/Transforms/Instrumentation/GCOVProfiling.cpp
index bcee0c5f04..66d8570108 100644
--- a/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ b/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -682,7 +682,9 @@ void GCOVProfiler::insertCounterWriteout(
"__llvm_gcov_init", M);
F->setUnnamedAddr(true);
F->setLinkage(GlobalValue::InternalLinkage);
- F->addFnAttr(Attribute::NoInline);
+ Attributes::Builder B;
+ B.addAttribute(Attributes::NoInline);
+ F->addFnAttr(Attributes::get(B));
BB = BasicBlock::Create(*Ctx, "entry", F);
Builder.SetInsertPoint(BB);
@@ -701,7 +703,9 @@ void GCOVProfiler::insertIndirectCounterIncrement() {
cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc());
Fn->setUnnamedAddr(true);
Fn->setLinkage(GlobalValue::InternalLinkage);
- Fn->addFnAttr(Attribute::NoInline);
+ Attributes::Builder B;
+ B.addAttribute(Attributes::NoInline);
+ Fn->addFnAttr(Attributes::get(B));
Type *Int32Ty = Type::getInt32Ty(*Ctx);
Type *Int64Ty = Type::getInt64Ty(*Ctx);
diff --git a/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
index 17b7775434..c6244a55c9 100644
--- a/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
+++ b/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
@@ -38,7 +38,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
@@ -47,6 +47,15 @@ using namespace llvm;
static cl::opt<std::string> ClBlackListFile("tsan-blacklist",
cl::desc("Blacklist file"), cl::Hidden);
+static cl::opt<bool> ClInstrumentMemoryAccesses(
+ "tsan-instrument-memory-accesses", cl::init(true),
+ cl::desc("Instrument memory accesses"), cl::Hidden);
+static cl::opt<bool> ClInstrumentFuncEntryExit(
+ "tsan-instrument-func-entry-exit", cl::init(true),
+ cl::desc("Instrument function entry and exit"), cl::Hidden);
+static cl::opt<bool> ClInstrumentAtomics(
+ "tsan-instrument-atomics", cl::init(true),
+ cl::desc("Instrument atomics"), cl::Hidden);
STATISTIC(NumInstrumentedReads, "Number of instrumented reads");
STATISTIC(NumInstrumentedWrites, "Number of instrumented writes");
@@ -76,7 +85,7 @@ struct ThreadSanitizer : public FunctionPass {
bool addrPointsToConstantData(Value *Addr);
int getMemoryAccessFuncIndex(Value *Addr);
- TargetData *TD;
+ DataLayout *TD;
OwningPtr<BlackList> BL;
IntegerType *OrdTy;
// Callbacks to run-time library are computed in doInitialization.
@@ -118,7 +127,7 @@ static Function *checkInterfaceFunction(Constant *FuncOrBitcast) {
}
bool ThreadSanitizer::doInitialization(Module &M) {
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
if (!TD)
return false;
BL.reset(new BlackList(ClBlackListFile));
@@ -284,17 +293,19 @@ bool ThreadSanitizer::runOnFunction(Function &F) {
// (e.g. variables that do not escape, etc).
// Instrument memory accesses.
- for (size_t i = 0, n = AllLoadsAndStores.size(); i < n; ++i) {
- Res |= instrumentLoadOrStore(AllLoadsAndStores[i]);
- }
+ if (ClInstrumentMemoryAccesses)
+ for (size_t i = 0, n = AllLoadsAndStores.size(); i < n; ++i) {
+ Res |= instrumentLoadOrStore(AllLoadsAndStores[i]);
+ }
// Instrument atomic memory accesses.
- for (size_t i = 0, n = AtomicAccesses.size(); i < n; ++i) {
- Res |= instrumentAtomic(AtomicAccesses[i]);
- }
+ if (ClInstrumentAtomics)
+ for (size_t i = 0, n = AtomicAccesses.size(); i < n; ++i) {
+ Res |= instrumentAtomic(AtomicAccesses[i]);
+ }
// Instrument function entry/exit points if there were instrumented accesses.
- if (Res || HasCalls) {
+ if ((Res || HasCalls) && ClInstrumentFuncEntryExit) {
IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI());
Value *ReturnAddress = IRB.CreateCall(
Intrinsic::getDeclaration(F.getParent(), Intrinsic::returnaddress),
@@ -350,7 +361,8 @@ static ConstantInt *createOrdering(IRBuilder<> *IRB, AtomicOrdering ord) {
case AcquireRelease: v = 1 << 4; break;
case SequentiallyConsistent: v = 1 << 5; break;
}
- return IRB->getInt32(v);
+ // +100500 is temporal to migrate to new enum values.
+ return IRB->getInt32(v + 100500);
}
bool ThreadSanitizer::instrumentAtomic(Instruction *I) {
diff --git a/lib/Transforms/Scalar/CodeGenPrepare.cpp b/lib/Transforms/Scalar/CodeGenPrepare.cpp
index 305d70f27b..2a52580eaa 100644
--- a/lib/Transforms/Scalar/CodeGenPrepare.cpp
+++ b/lib/Transforms/Scalar/CodeGenPrepare.cpp
@@ -38,7 +38,7 @@
#include "llvm/Support/PatternMatch.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Transforms/Utils/AddrModeMatcher.h"
@@ -149,14 +149,15 @@ bool CodeGenPrepare::runOnFunction(Function &F) {
TLInfo = &getAnalysis<TargetLibraryInfo>();
DT = getAnalysisIfAvailable<DominatorTree>();
PFI = getAnalysisIfAvailable<ProfileInfo>();
- OptSize = F.getFnAttributes().hasOptimizeForSizeAttr();
+ OptSize = F.getFnAttributes().hasAttribute(Attributes::OptimizeForSize);
/// This optimization identifies DIV instructions that can be
/// profitably bypassed and carried out with a shorter, faster divide.
if (TLI && TLI->isSlowDivBypassed()) {
- const DenseMap<Type*, Type*> &BypassTypeMap = TLI->getBypassSlowDivTypes();
+ const DenseMap<unsigned int, unsigned int> &BypassWidths =
+ TLI->getBypassSlowDivWidths();
for (Function::iterator I = F.begin(); I != F.end(); I++)
- EverMadeChange |= bypassSlowDivision(F, I, BypassTypeMap);
+ EverMadeChange |= bypassSlowDivision(F, I, BypassWidths);
}
// Eliminate blocks that contain only PHI nodes and an
@@ -622,7 +623,7 @@ bool CodeGenPrepare::OptimizeCallInst(CallInst *CI) {
// happens.
WeakVH IterHandle(CurInstIterator);
- replaceAndRecursivelySimplify(CI, RetVal, TLI ? TLI->getTargetData() : 0,
+ replaceAndRecursivelySimplify(CI, RetVal, TLI ? TLI->getDataLayout() : 0,
TLInfo, ModifiedDT ? 0 : DT);
// If the iterator instruction was recursively deleted, start over at the
@@ -646,8 +647,8 @@ bool CodeGenPrepare::OptimizeCallInst(CallInst *CI) {
// From here on out we're working with named functions.
if (CI->getCalledFunction() == 0) return false;
- // We'll need TargetData from here on out.
- const TargetData *TD = TLI ? TLI->getTargetData() : 0;
+ // We'll need DataLayout from here on out.
+ const DataLayout *TD = TLI ? TLI->getDataLayout() : 0;
if (!TD) return false;
// Lower all default uses of _chk calls. This is very similar
@@ -714,7 +715,8 @@ bool CodeGenPrepare::DupRetToEnableTailCallOpts(ReturnInst *RI) {
// See llvm::isInTailCallPosition().
const Function *F = BB->getParent();
Attributes CallerRetAttr = F->getAttributes().getRetAttributes();
- if ((CallerRetAttr & Attribute::ZExt) || (CallerRetAttr & Attribute::SExt))
+ if (CallerRetAttr.hasAttribute(Attributes::ZExt) ||
+ CallerRetAttr.hasAttribute(Attributes::SExt))
return false;
// Make sure there are no instructions between the PHI and return, or that the
@@ -929,7 +931,7 @@ bool CodeGenPrepare::OptimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
DEBUG(dbgs() << "CGP: SINKING nonlocal addrmode: " << AddrMode << " for "
<< *MemoryInst);
Type *IntPtrTy =
- TLI->getTargetData()->getIntPtrType(AccessTy->getContext());
+ TLI->getDataLayout()->getIntPtrType(AccessTy->getContext());
Value *Result = 0;
diff --git a/lib/Transforms/Scalar/ConstantProp.cpp b/lib/Transforms/Scalar/ConstantProp.cpp
index 5430f62538..369720b3dc 100644
--- a/lib/Transforms/Scalar/ConstantProp.cpp
+++ b/lib/Transforms/Scalar/ConstantProp.cpp
@@ -24,7 +24,7 @@
#include "llvm/Constant.h"
#include "llvm/Instruction.h"
#include "llvm/Pass.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Support/InstIterator.h"
#include "llvm/ADT/Statistic.h"
@@ -67,7 +67,7 @@ bool ConstantPropagation::runOnFunction(Function &F) {
WorkList.insert(&*i);
}
bool Changed = false;
- TargetData *TD = getAnalysisIfAvailable<TargetData>();
+ DataLayout *TD = getAnalysisIfAvailable<DataLayout>();
TargetLibraryInfo *TLI = &getAnalysis<TargetLibraryInfo>();
while (!WorkList.empty()) {
diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp
index 301ee2f663..602e5a4785 100644
--- a/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -29,7 +29,7 @@
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Support/Debug.h"
@@ -199,7 +199,7 @@ getLocForWrite(Instruction *Inst, AliasAnalysis &AA) {
// If we don't have target data around, an unknown size in Location means
// that we should use the size of the pointee type. This isn't valid for
// memset/memcpy, which writes more than an i8.
- if (Loc.Size == AliasAnalysis::UnknownSize && AA.getTargetData() == 0)
+ if (Loc.Size == AliasAnalysis::UnknownSize && AA.getDataLayout() == 0)
return AliasAnalysis::Location();
return Loc;
}
@@ -213,7 +213,7 @@ getLocForWrite(Instruction *Inst, AliasAnalysis &AA) {
// If we don't have target data around, an unknown size in Location means
// that we should use the size of the pointee type. This isn't valid for
// init.trampoline, which writes more than an i8.
- if (AA.getTargetData() == 0) return AliasAnalysis::Location();
+ if (AA.getDataLayout() == 0) return AliasAnalysis::Location();
// FIXME: We don't know the size of the trampoline, so we can't really
// handle it here.
@@ -318,7 +318,7 @@ static Value *getStoredPointerOperand(Instruction *I) {
static uint64_t getPointerSize(const Value *V, AliasAnalysis &AA) {
uint64_t Size;
- if (getObjectSize(V, Size, AA.getTargetData(), AA.getTargetLibraryInfo()))
+ if (getObjectSize(V, Size, AA.getDataLayout(), AA.getTargetLibraryInfo()))
return Size;
return AliasAnalysis::UnknownSize;
}
@@ -351,10 +351,10 @@ static OverwriteResult isOverwrite(const AliasAnalysis::Location &Later,
// comparison.
if (Later.Size == AliasAnalysis::UnknownSize ||
Earlier.Size == AliasAnalysis::UnknownSize) {
- // If we have no TargetData information around, then the size of the store
+ // If we have no DataLayout information around, then the size of the store
// is inferrable from the pointee type. If they are the same type, then
// we know that the store is safe.
- if (AA.getTargetData() == 0 &&
+ if (AA.getDataLayout() == 0 &&
Later.Ptr->getType() == Earlier.Ptr->getType())
return OverwriteComplete;
@@ -370,13 +370,13 @@ static OverwriteResult isOverwrite(const AliasAnalysis::Location &Later,
// larger than the earlier one.
if (Later.Size == AliasAnalysis::UnknownSize ||
Earlier.Size == AliasAnalysis::UnknownSize ||
- AA.getTargetData() == 0)
+ AA.getDataLayout() == 0)
return OverwriteUnknown;
// Check to see if the later store is to the entire object (either a global,
// an alloca, or a byval argument). If so, then it clearly overwrites any
// other store to the same object.
- const TargetData &TD = *AA.getTargetData();
+ const DataLayout &TD = *AA.getDataLayout();
const Value *UO1 = GetUnderlyingObject(P1, &TD),
*UO2 = GetUnderlyingObject(P2, &TD);
diff --git a/lib/Transforms/Scalar/EarlyCSE.cpp b/lib/Transforms/Scalar/EarlyCSE.cpp
index 258a961df4..101009dd64 100644
--- a/lib/Transforms/Scalar/EarlyCSE.cpp
+++ b/lib/Transforms/Scalar/EarlyCSE.cpp
@@ -18,11 +18,12 @@
#include "llvm/Pass.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/InstructionSimplify.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/RecyclingAllocator.h"
+#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/ScopedHashTable.h"
#include "llvm/ADT/Statistic.h"
#include <deque>
@@ -90,35 +91,56 @@ template<> struct DenseMapInfo<SimpleValue> {
unsigned DenseMapInfo<SimpleValue>::getHashValue(SimpleValue Val) {
Instruction *Inst = Val.Inst;
-
// Hash in all of the operands as pointers.
- unsigned Res = 0;
- for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i)
- Res ^= getHash(Inst->getOperand(i)) << (i & 0xF);
+ if (BinaryOperator* BinOp = dyn_cast<BinaryOperator>(Inst)) {
+ Value *LHS = BinOp->getOperand(0);
+ Value *RHS = BinOp->getOperand(1);
+ if (BinOp->isCommutative() && BinOp->getOperand(0) > BinOp->getOperand(1))
+ std::swap(LHS, RHS);
+
+ if (isa<OverflowingBinaryOperator>(BinOp)) {
+ // Hash the overflow behavior
+ unsigned Overflow =
+ BinOp->hasNoSignedWrap() * OverflowingBinaryOperator::NoSignedWrap |
+ BinOp->hasNoUnsignedWrap() * OverflowingBinaryOperator::NoUnsignedWrap;
+ return hash_combine(BinOp->getOpcode(), Overflow, LHS, RHS);
+ }
- if (CastInst *CI = dyn_cast<CastInst>(Inst))
- Res ^= getHash(CI->getType());
- else if (CmpInst *CI = dyn_cast<CmpInst>(Inst))
- Res ^= CI->getPredicate();
- else if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(Inst)) {
- for (ExtractValueInst::idx_iterator I = EVI->idx_begin(),
- E = EVI->idx_end(); I != E; ++I)
- Res ^= *I;
- } else if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(Inst)) {
- for (InsertValueInst::idx_iterator I = IVI->idx_begin(),
- E = IVI->idx_end(); I != E; ++I)
- Res ^= *I;
- } else {
- // nothing extra to hash in.
- assert((isa<CallInst>(Inst) ||
- isa<BinaryOperator>(Inst) || isa<GetElementPtrInst>(Inst) ||
- isa<SelectInst>(Inst) || isa<ExtractElementInst>(Inst) ||
- isa<InsertElementInst>(Inst) || isa<ShuffleVectorInst>(Inst)) &&
- "Invalid/unknown instruction");
+ return hash_combine(BinOp->getOpcode(), LHS, RHS);
}
+ if (CmpInst *CI = dyn_cast<CmpInst>(Inst)) {
+ Value *LHS = CI->getOperand(0);
+ Value *RHS = CI->getOperand(1);
+ CmpInst::Predicate Pred = CI->getPredicate();
+ if (Inst->getOperand(0) > Inst->getOperand(1)) {
+ std::swap(LHS, RHS);
+ Pred = CI->getSwappedPredicate();
+ }
+ return hash_combine(Inst->getOpcode(), Pred, LHS, RHS);
+ }
+
+ if (CastInst *CI = dyn_cast<CastInst>(Inst))
+ return hash_combine(CI->getOpcode(), CI->getType(), CI->getOperand(0));
+
+ if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(Inst))
+ return hash_combine(EVI->getOpcode(), EVI->getOperand(0),
+ hash_combine_range(EVI->idx_begin(), EVI->idx_end()));
+
+ if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(Inst))
+ return hash_combine(IVI->getOpcode(), IVI->getOperand(0),
+ IVI->getOperand(1),
+ hash_combine_range(IVI->idx_begin(), IVI->idx_end()));
+
+ assert((isa<CallInst>(Inst) || isa<BinaryOperator>(Inst) ||
+ isa<GetElementPtrInst>(Inst) || isa<SelectInst>(Inst) ||
+ isa<ExtractElementInst>(Inst) || isa<InsertElementInst>(Inst) ||
+ isa<ShuffleVectorInst>(Inst)) && "Invalid/unknown instruction");
+
// Mix in the opcode.
- return (Res << 1) ^ Inst->getOpcode();
+ return hash_combine(Inst->getOpcode(),
+ hash_combine_range(Inst->value_op_begin(),
+ Inst->value_op_end()));
}
bool DenseMapInfo<SimpleValue>::isEqual(SimpleValue LHS, SimpleValue RHS) {
@@ -128,7 +150,41 @@ bool DenseMapInfo<SimpleValue>::isEqual(SimpleValue LHS, SimpleValue RHS) {
return LHSI == RHSI;
if (LHSI->getOpcode() != RHSI->getOpcode()) return false;
- return LHSI->isIdenticalTo(RHSI);
+ if (LHSI->isIdenticalTo(RHSI)) return true;
+
+ // If we're not strictly identical, we still might be a commutable instruction
+ if (BinaryOperator *LHSBinOp = dyn_cast<BinaryOperator>(LHSI)) {
+ if (!LHSBinOp->isCommutative())
+ return false;
+
+ assert(isa<BinaryOperator>(RHSI)
+ && "same opcode, but different instruction type?");
+ BinaryOperator *RHSBinOp = cast<BinaryOperator>(RHSI);
+
+ // Check overflow attributes
+ if (isa<OverflowingBinaryOperator>(LHSBinOp)) {
+ assert(isa<OverflowingBinaryOperator>(RHSBinOp)
+ && "same opcode, but different operator type?");
+ if (LHSBinOp->hasNoUnsignedWrap() != RHSBinOp->hasNoUnsignedWrap() ||
+ LHSBinOp->hasNoSignedWrap() != RHSBinOp->hasNoSignedWrap())
+ return false;
+ }
+
+ // Commuted equality
+ return LHSBinOp->getOperand(0) == RHSBinOp->getOperand(1) &&
+ LHSBinOp->getOperand(1) == RHSBinOp->getOperand(0);
+ }
+ if (CmpInst *LHSCmp = dyn_cast<CmpInst>(LHSI)) {
+ assert(isa<CmpInst>(RHSI)
+ && "same opcode, but different instruction type?");
+ CmpInst *RHSCmp = cast<CmpInst>(RHSI);
+ // Commuted equality
+ return LHSCmp->getOperand(0) == RHSCmp->getOperand(1) &&
+ LHSCmp->getOperand(1) == RHSCmp->getOperand(0) &&
+ LHSCmp->getSwappedPredicate() == RHSCmp->getPredicate();
+ }
+
+ return false;
}
//===----------------------------------------------------------------------===//
@@ -216,7 +272,7 @@ namespace {
/// cases.
class EarlyCSE : public FunctionPass {
public:
- const TargetData *TD;
+ const DataLayout *TD;
const TargetLibraryInfo *TLI;
DominatorTree *DT;
typedef RecyclingAllocator<BumpPtrAllocator,
@@ -508,7 +564,7 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
bool EarlyCSE::runOnFunction(Function &F) {
std::deque<StackNode *> nodesToProcess;
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
TLI = &getAnalysis<TargetLibraryInfo>();
DT = &getAnalysis<DominatorTree>();
diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp
index e67d8af46c..eb0da20abb 100644
--- a/lib/Transforms/Scalar/GVN.cpp
+++ b/lib/Transforms/Scalar/GVN.cpp
@@ -41,7 +41,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/PatternMatch.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/SSAUpdater.h"
@@ -503,7 +503,7 @@ namespace {
bool NoLoads;
MemoryDependenceAnalysis *MD;
DominatorTree *DT;
- const TargetData *TD;
+ const DataLayout *TD;
const TargetLibraryInfo *TLI;
ValueTable VN;
@@ -535,7 +535,7 @@ namespace {
InstrsToErase.push_back(I);
}
- const TargetData *getTargetData() const { return TD; }
+ const DataLayout *getDataLayout() const { return TD; }
DominatorTree &getDominatorTree() const { return *DT; }
AliasAnalysis *getAliasAnalysis() const { return VN.getAliasAnalysis(); }
MemoryDependenceAnalysis &getMemDep() const { return *MD; }
@@ -730,7 +730,7 @@ SpeculationFailure:
/// CoerceAvailableValueToLoadType will succeed.
static bool CanCoerceMustAliasedValueToLoad(Value *StoredVal,
Type *LoadTy,
- const TargetData &TD) {
+ const DataLayout &TD) {
// If the loaded or stored value is an first class array or struct, don't try
// to transform them. We need to be able to bitcast to integer.
if (LoadTy->isStructTy() || LoadTy->isArrayTy() ||
@@ -756,7 +756,7 @@ static bool CanCoerceMustAliasedValueToLoad(Value *StoredVal,
static Value *CoerceAvailableValueToLoadType(Value *StoredVal,
Type *LoadedTy,
Instruction *InsertPt,
- const TargetData &TD) {
+ const DataLayout &TD) {
if (!CanCoerceMustAliasedValueToLoad(StoredVal, LoadedTy, TD))
return 0;
@@ -842,7 +842,7 @@ static Value *CoerceAvailableValueToLoadType(Value *StoredVal,
static int AnalyzeLoadFromClobberingWrite(Type *LoadTy, Value *LoadPtr,
Value *WritePtr,
uint64_t WriteSizeInBits,
- const TargetData &TD) {
+ const DataLayout &TD) {
// If the loaded or stored value is a first class array or struct, don't try
// to transform them. We need to be able to bitcast to integer.
if (LoadTy->isStructTy() || LoadTy->isArrayTy())
@@ -915,7 +915,7 @@ static int AnalyzeLoadFromClobberingWrite(Type *LoadTy, Value *LoadPtr,
/// memdep query of a load that ends up being a clobbering store.
static int AnalyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr,
StoreInst *DepSI,
- const TargetData &TD) {
+ const DataLayout &TD) {
// Cannot handle reading from store of first-class aggregate yet.
if (DepSI->getValueOperand()->getType()->isStructTy() ||
DepSI->getValueOperand()->getType()->isArrayTy())
@@ -931,7 +931,7 @@ static int AnalyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr,
/// memdep query of a load that ends up being clobbered by another load. See if
/// the other load can feed into the second load.
static int AnalyzeLoadFromClobberingLoad(Type *LoadTy, Value *LoadPtr,
- LoadInst *DepLI, const TargetData &TD){
+ LoadInst *DepLI, const DataLayout &TD){
// Cannot handle reading from store of first-class aggregate yet.
if (DepLI->getType()->isStructTy() || DepLI->getType()->isArrayTy())
return -1;
@@ -959,7 +959,7 @@ static int AnalyzeLoadFromClobberingLoad(Type *LoadTy, Value *LoadPtr,
static int AnalyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr,
MemIntrinsic *MI,
- const TargetData &TD) {
+ const DataLayout &TD) {
// If the mem operation is a non-constant size, we can't handle it.
ConstantInt *SizeCst = dyn_cast<ConstantInt>(MI->getLength());
if (SizeCst == 0) return -1;
@@ -1009,7 +1009,7 @@ static int AnalyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr,
/// before we give up.
static Value *GetStoreValueForLoad(Value *SrcVal, unsigned Offset,
Type *LoadTy,
- Instruction *InsertPt, const TargetData &TD){
+ Instruction *InsertPt, const DataLayout &TD){
LLVMContext &Ctx = SrcVal->getType()->getContext();
uint64_t StoreSize = (TD.getTypeSizeInBits(SrcVal->getType()) + 7) / 8;
@@ -1048,7 +1048,7 @@ static Value *GetStoreValueForLoad(Value *SrcVal, unsigned Offset,
static Value *GetLoadValueForLoad(LoadInst *SrcVal, unsigned Offset,
Type *LoadTy, Instruction *InsertPt,
GVN &gvn) {
- const TargetData &TD = *gvn.getTargetData();
+ const DataLayout &TD = *gvn.getDataLayout();
// If Offset+LoadTy exceeds the size of SrcVal, then we must be wanting to
// widen SrcVal out to a larger load.
unsigned SrcValSize = TD.getTypeStoreSize(SrcVal->getType());
@@ -1107,7 +1107,7 @@ static Value *GetLoadValueForLoad(LoadInst *SrcVal, unsigned Offset,
/// memdep query of a load that ends up being a clobbering mem intrinsic.
static Value *GetMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset,
Type *LoadTy, Instruction *InsertPt,
- const TargetData &TD){
+ const DataLayout &TD){
LLVMContext &Ctx = LoadTy->getContext();
uint64_t LoadSize = TD.getTypeSizeInBits(LoadTy)/8;
@@ -1231,7 +1231,7 @@ struct AvailableValueInBlock {
if (isSimpleValue()) {
Res = getSimpleValue();
if (Res->getType() != LoadTy) {
- const TargetData *TD = gvn.getTargetData();
+ const DataLayout *TD = gvn.getDataLayout();
assert(TD && "Need target data to handle type mismatch case");
Res = GetStoreValueForLoad(Res, Offset, LoadTy, BB->getTerminator(),
*TD);
@@ -1253,7 +1253,7 @@ struct AvailableValueInBlock {
<< *Res << '\n' << "\n\n\n");
}
} else {
- const TargetData *TD = gvn.getTargetData();
+ const DataLayout *TD = gvn.getDataLayout();
assert(TD && "Need target data to handle type mismatch case");
Res = GetMemInstValueForLoad(getMemIntrinValue(), Offset,
LoadTy, BB->getTerminator(), *TD);
@@ -2295,7 +2295,7 @@ bool GVN::runOnFunction(Function& F) {
if (!NoLoads)
MD = &getAnalysis<MemoryDependenceAnalysis>();
DT = &getAnalysis<DominatorTree>();
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
TLI = &getAnalysis<TargetLibraryInfo>();
VN.setAliasAnalysis(&getAnalysis<AliasAnalysis>());
VN.setMemDep(MD);
diff --git a/lib/Transforms/Scalar/GlobalMerge.cpp b/lib/Transforms/Scalar/GlobalMerge.cpp
index b36a3cb776..6301aad610 100644
--- a/lib/Transforms/Scalar/GlobalMerge.cpp
+++ b/lib/Transforms/Scalar/GlobalMerge.cpp
@@ -62,7 +62,7 @@
#include "llvm/Intrinsics.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/ADT/Statistic.h"
@@ -98,9 +98,9 @@ namespace {
}
struct GlobalCmp {
- const TargetData *TD;
+ const DataLayout *TD;
- GlobalCmp(const TargetData *td) : TD(td) { }
+ GlobalCmp(const DataLayout *td) : TD(td) { }
bool operator()(const GlobalVariable *GV1, const GlobalVariable *GV2) {
Type *Ty1 = cast<PointerType>(GV1->getType())->getElementType();
@@ -119,7 +119,7 @@ INITIALIZE_PASS(GlobalMerge, "global-merge",
bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
Module &M, bool isConst) const {
- const TargetData *TD = TLI->getTargetData();
+ const DataLayout *TD = TLI->getDataLayout();
// FIXME: Infer the maximum possible offset depending on the actual users
// (these max offsets are different for the users inside Thumb or ARM
@@ -170,7 +170,7 @@ bool GlobalMerge::doMerge(SmallVectorImpl<GlobalVariable*> &Globals,
bool GlobalMerge::doInitialization(Module &M) {
SmallVector<GlobalVariable*, 16> Globals, ConstGlobals, BSSGlobals;
- const TargetData *TD = TLI->getTargetData();
+ const DataLayout *TD = TLI->getDataLayout();
unsigned MaxOffset = TLI->getMaximalGlobalOffset();
bool Changed = false;
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp
index c933a178d7..78630b2a9f 100644
--- a/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -43,7 +43,7 @@
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/SimplifyIndVar.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
@@ -68,7 +68,7 @@ namespace {
LoopInfo *LI;
ScalarEvolution *SE;
DominatorTree *DT;
- TargetData *TD;
+ DataLayout *TD;
TargetLibraryInfo *TLI;
SmallVector<WeakVH, 16> DeadInsts;
@@ -597,13 +597,13 @@ namespace {
class WideIVVisitor : public IVVisitor {
ScalarEvolution *SE;
- const TargetData *TD;
+ const DataLayout *TD;
public:
WideIVInfo WI;
WideIVVisitor(PHINode *NarrowIV, ScalarEvolution *SCEV,
- const TargetData *TData) :
+ const DataLayout *TData) :
SE(SCEV), TD(TData) { WI.NarrowIV = NarrowIV; }
// Implement the interface used by simplifyUsersOfIV.
@@ -1261,8 +1261,13 @@ static bool needsLFTR(Loop *L, DominatorTree *DT) {
if (!Phi)
return true;
+ // Do LFTR if PHI node is defined in the loop, but is *not* a counter.
+ int Idx = Phi->getBasicBlockIndex(L->getLoopLatch());
+ if (Idx < 0)
+ return true;
+
// Do LFTR if the exit condition's IV is *not* a simple counter.
- Value *IncV = Phi->getIncomingValueForBlock(L->getLoopLatch());
+ Value *IncV = Phi->getIncomingValue(Idx);
return Phi != getLoopPhiForCounter(IncV, L, DT);
}
@@ -1341,7 +1346,7 @@ static bool AlmostDeadIV(PHINode *Phi, BasicBlock *LatchBlock, Value *Cond) {
/// could at least handle constant BECounts.
static PHINode *
FindLoopCounter(Loop *L, const SCEV *BECount,
- ScalarEvolution *SE, DominatorTree *DT, const TargetData *TD) {
+ ScalarEvolution *SE, DominatorTree *DT, const DataLayout *TD) {
uint64_t BCWidth = SE->getTypeSizeInBits(BECount->getType());
Value *Cond =
@@ -1698,7 +1703,7 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
LI = &getAnalysis<LoopInfo>();
SE = &getAnalysis<ScalarEvolution>();
DT = &getAnalysis<DominatorTree>();
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
TLI = getAnalysisIfAvailable<TargetLibraryInfo>();
DeadInsts.clear();
diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp
index 20844c6cd5..e7ffa09f17 100644
--- a/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/lib/Transforms/Scalar/JumpThreading.cpp
@@ -23,7 +23,7 @@
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/SSAUpdater.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
@@ -75,7 +75,7 @@ namespace {
/// revectored to the false side of the second if.
///
class JumpThreading : public FunctionPass {
- TargetData *TD;
+ DataLayout *TD;
TargetLibraryInfo *TLI;
LazyValueInfo *LVI;
#ifdef NDEBUG
@@ -147,7 +147,7 @@ FunctionPass *llvm::createJumpThreadingPass() { return new JumpThreading(); }
///
bool JumpThreading::runOnFunction(Function &F) {
DEBUG(dbgs() << "Jump threading on function '" << F.getName() << "'\n");
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
TLI = &getAnalysis<TargetLibraryInfo>();
LVI = &getAnalysis<LazyValueInfo>();
diff --git a/lib/Transforms/Scalar/LICM.cpp b/lib/Transforms/Scalar/LICM.cpp
index 99bedce6c7..4818437c24 100644
--- a/lib/Transforms/Scalar/LICM.cpp
+++ b/lib/Transforms/Scalar/LICM.cpp
@@ -46,7 +46,7 @@
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/SSAUpdater.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/CommandLine.h"
@@ -100,7 +100,7 @@ namespace {
LoopInfo *LI; // Current LoopInfo
DominatorTree *DT; // Dominator Tree for the current Loop.
- TargetData *TD; // TargetData for constant folding.
+ DataLayout *TD; // DataLayout for constant folding.
TargetLibraryInfo *TLI; // TargetLibraryInfo for constant folding.
// State that is updated as we process loops.
@@ -207,7 +207,7 @@ bool LICM::runOnLoop(Loop *L, LPPassManager &LPM) {
AA = &getAnalysis<AliasAnalysis>();
DT = &getAnalysis<DominatorTree>();
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
TLI = &getAnalysis<TargetLibraryInfo>();
CurAST = new AliasSetTracker(*AA);
diff --git a/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index 1553328c07..a44e798f12 100644
--- a/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -54,7 +54,7 @@
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/Utils/Local.h"
using namespace llvm;
@@ -65,7 +65,7 @@ STATISTIC(NumMemCpy, "Number of memcpy's formed from loop load+stores");
namespace {
class LoopIdiomRecognize : public LoopPass {
Loop *CurLoop;
- const TargetData *TD;
+ const DataLayout *TD;
DominatorTree *DT;
ScalarEvolution *SE;
TargetLibraryInfo *TLI;
@@ -199,7 +199,7 @@ bool LoopIdiomRecognize::runOnLoop(Loop *L, LPPassManager &LPM) {
return false;
// We require target data for now.
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
if (TD == 0) return false;
DT = &getAnalysis<DominatorTree>();
@@ -408,7 +408,7 @@ static bool mayLoopAccessLocation(Value *Ptr,AliasAnalysis::ModRefResult Access,
///
/// Note that we don't ever attempt to use memset_pattern8 or 4, because these
/// just replicate their input array and then pass on to memset_pattern16.
-static Constant *getMemSetPatternValue(Value *V, const TargetData &TD) {
+static Constant *getMemSetPatternValue(Value *V, const DataLayout &TD) {
// If the value isn't a constant, we can't promote it to being in a constant
// array. We could theoretically do a store to an alloca or something, but
// that doesn't seem worthwhile.
diff --git a/lib/Transforms/Scalar/LoopInstSimplify.cpp b/lib/Transforms/Scalar/LoopInstSimplify.cpp
index f5daa7b44e..558f62e6b4 100644
--- a/lib/Transforms/Scalar/LoopInstSimplify.cpp
+++ b/lib/Transforms/Scalar/LoopInstSimplify.cpp
@@ -18,7 +18,7 @@
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h"
@@ -66,7 +66,7 @@ Pass *llvm::createLoopInstSimplifyPass() {
bool LoopInstSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>();
LoopInfo *LI = &getAnalysis<LoopInfo>();
- const TargetData *TD = getAnalysisIfAvailable<TargetData>();
+ const DataLayout *TD = getAnalysisIfAvailable<DataLayout>();
const TargetLibraryInfo *TLI = &getAnalysis<TargetLibraryInfo>();
SmallVector<BasicBlock*, 8> ExitBlocks;
diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index 1d3d156887..958348d9fa 100644
--- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -54,7 +54,7 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "loop-reduce"
-#include "llvm/Transforms/Scalar.h"
+#include "llvm/AddressingMode.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
@@ -64,6 +64,7 @@
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/ScalarEvolutionExpander.h"
#include "llvm/Assembly/Writer.h"
+#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/ADT/SmallBitVector.h"
@@ -225,7 +226,7 @@ namespace {
struct Formula {
/// AM - This is used to represent complex addressing, as well as other kinds
/// of interesting uses.
- TargetLowering::AddrMode AM;
+ AddrMode AM;
/// BaseRegs - The list of "base" registers for this use. When this is
/// non-empty, AM.HasBaseReg should be set to true.
@@ -1269,7 +1270,7 @@ void LSRUse::dump() const {
/// isLegalUse - Test whether the use described by AM is "legal", meaning it can
/// be completely folded into the user instruction at isel time. This includes
/// address-mode folding and special icmp tricks.
-static bool isLegalUse(const TargetLowering::AddrMode &AM,
+static bool isLegalUse(const AddrMode &AM,
LSRUse::KindType Kind, Type *AccessTy,
const TargetLowering *TLI) {
switch (Kind) {
@@ -1326,7 +1327,7 @@ static bool isLegalUse(const TargetLowering::AddrMode &AM,
llvm_unreachable("Invalid LSRUse Kind!");
}
-static bool isLegalUse(TargetLowering::AddrMode AM,
+static bool isLegalUse(AddrMode AM,
int64_t MinOffset, int64_t MaxOffset,
LSRUse::KindType Kind, Type *AccessTy,
const TargetLowering *TLI) {
@@ -1357,7 +1358,7 @@ static bool isAlwaysFoldable(int64_t BaseOffs,
// Conservatively, create an address with an immediate and a
// base and a scale.
- TargetLowering::AddrMode AM;
+ AddrMode AM;
AM.BaseOffs = BaseOffs;
AM.BaseGV = BaseGV;
AM.HasBaseReg = HasBaseReg;
@@ -1395,7 +1396,7 @@ static bool isAlwaysFoldable(const SCEV *S,
// Conservatively, create an address with an immediate and a
// base and a scale.
- TargetLowering::AddrMode AM;
+ AddrMode AM;
AM.BaseOffs = BaseOffs;
AM.BaseGV = BaseGV;
AM.HasBaseReg = HasBaseReg;
@@ -2020,7 +2021,7 @@ LSRInstance::OptimizeLoopTermCond() {
goto decline_post_inc;
// Check for possible scaled-address reuse.
Type *AccessTy = getAccessType(UI->getUser());
- TargetLowering::AddrMode AM;
+ AddrMode AM;
AM.Scale = C->getSExtValue();
if (TLI->isLegalAddressingMode(AM, AccessTy))
goto decline_post_inc;
diff --git a/lib/Transforms/Scalar/LoopUnrollPass.cpp b/lib/Transforms/Scalar/LoopUnrollPass.cpp
index f8709a537f..0d781ac977 100644
--- a/lib/Transforms/Scalar/LoopUnrollPass.cpp
+++ b/lib/Transforms/Scalar/LoopUnrollPass.cpp
@@ -22,7 +22,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/UnrollLoop.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include <climits>
using namespace llvm;
@@ -113,7 +113,7 @@ Pass *llvm::createLoopUnrollPass(int Threshold, int Count, int AllowPartial) {
/// ApproximateLoopSize - Approximate the size of the loop.
static unsigned ApproximateLoopSize(const Loop *L, unsigned &NumCalls,
- const TargetData *TD) {
+ const DataLayout *TD) {
CodeMetrics Metrics;
for (Loop::block_iterator I = L->block_begin(), E = L->block_end();
I != E; ++I)
@@ -145,7 +145,8 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
// not user specified.
unsigned Threshold = CurrentThreshold;
if (!UserThreshold &&
- Header->getParent()->getFnAttributes().hasOptimizeForSizeAttr())
+ Header->getParent()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize))
Threshold = OptSizeUnrollThreshold;
// Find trip count and trip multiple if count is not available
@@ -178,7 +179,7 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
// Enforce the threshold.
if (Threshold != NoThreshold) {
- const TargetData *TD = getAnalysisIfAvailable<TargetData>();
+ const DataLayout *TD = getAnalysisIfAvailable<DataLayout>();
unsigned NumInlineCandidates;
unsigned LoopSize = ApproximateLoopSize(L, NumInlineCandidates, TD);
DEBUG(dbgs() << " Loop Size = " << LoopSize << "\n");
diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp
index 74c8f43ec2..15b168fe2a 100644
--- a/lib/Transforms/Scalar/LoopUnswitch.cpp
+++ b/lib/Transforms/Scalar/LoopUnswitch.cpp
@@ -638,7 +638,8 @@ bool LoopUnswitch::UnswitchIfProfitable(Value *LoopCond, Constant *Val) {
// Check to see if it would be profitable to unswitch current loop.
// Do not do non-trivial unswitch while optimizing for size.
- if (OptimizeForSize || F->getFnAttributes().hasOptimizeForSizeAttr())
+ if (OptimizeForSize ||
+ F->getFnAttributes().hasAttribute(Attributes::OptimizeForSize))
return false;
UnswitchNontrivialCondition(LoopCond, Val, currentLoop);
diff --git a/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index 35acc79238..517657cf52 100644
--- a/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -27,7 +27,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/Utils/Local.h"
#include <list>
@@ -39,7 +39,7 @@ STATISTIC(NumMoveToCpy, "Number of memmoves converted to memcpy");
STATISTIC(NumCpyToSet, "Number of memcpys converted to memset");
static int64_t GetOffsetFromIndex(const GEPOperator *GEP, unsigned Idx,
- bool &VariableIdxFound, const TargetData &TD){
+ bool &VariableIdxFound, const DataLayout &TD){
// Skip over the first indices.
gep_type_iterator GTI = gep_type_begin(GEP);
for (unsigned i = 1; i != Idx; ++i, ++GTI)
@@ -72,7 +72,7 @@ static int64_t GetOffsetFromIndex(const GEPOperator *GEP, unsigned Idx,
/// constant offset, and return that constant offset. For example, Ptr1 might
/// be &A[42], and Ptr2 might be &A[40]. In this case offset would be -8.
static bool IsPointerOffset(Value *Ptr1, Value *Ptr2, int64_t &Offset,
- const TargetData &TD) {
+ const DataLayout &TD) {
Ptr1 = Ptr1->stripPointerCasts();
Ptr2 = Ptr2->stripPointerCasts();
GEPOperator *GEP1 = dyn_cast<GEPOperator>(Ptr1);
@@ -141,12 +141,12 @@ struct MemsetRange {
/// TheStores - The actual stores that make up this range.
SmallVector<Instruction*, 16> TheStores;
- bool isProfitableToUseMemset(const TargetData &TD) const;
+ bool isProfitableToUseMemset(const DataLayout &TD) const;
};
} // end anon namespace
-bool MemsetRange::isProfitableToUseMemset(const TargetData &TD) const {
+bool MemsetRange::isProfitableToUseMemset(const DataLayout &TD) const {
// If we found more than 4 stores to merge or 16 bytes, use memset.
if (TheStores.size() >= 4 || End-Start >= 16) return true;
@@ -192,9 +192,9 @@ class MemsetRanges {
/// because each element is relatively large and expensive to copy.
std::list<MemsetRange> Ranges;
typedef std::list<MemsetRange>::iterator range_iterator;
- const TargetData &TD;
+ const DataLayout &TD;
public:
- MemsetRanges(const TargetData &td) : TD(td) {}
+ MemsetRanges(const DataLayout &td) : TD(td) {}
typedef std::list<MemsetRange>::const_iterator const_iterator;
const_iterator begin() const { return Ranges.begin(); }
@@ -302,7 +302,7 @@ namespace {
class MemCpyOpt : public FunctionPass {
MemoryDependenceAnalysis *MD;
TargetLibraryInfo *TLI;
- const TargetData *TD;
+ const DataLayout *TD;
public:
static char ID; // Pass identification, replacement for typeid
MemCpyOpt() : FunctionPass(ID) {
@@ -332,7 +332,7 @@ namespace {
bool processMemCpy(MemCpyInst *M);
bool processMemMove(MemMoveInst *M);
bool performCallSlotOptzn(Instruction *cpy, Value *cpyDst, Value *cpySrc,
- uint64_t cpyLen, CallInst *C);
+ uint64_t cpyLen, unsigned cpyAlign, CallInst *C);
bool processMemCpyMemCpyDependence(MemCpyInst *M, MemCpyInst *MDep,
uint64_t MSize);
bool processByValArgument(CallSite CS, unsigned ArgNo);
@@ -509,10 +509,18 @@ bool MemCpyOpt::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
}
if (C) {
+ unsigned storeAlign = SI->getAlignment();
+ if (!storeAlign)
+ storeAlign = TD->getABITypeAlignment(SI->getOperand(0)->getType());
+ unsigned loadAlign = LI->getAlignment();
+ if (!loadAlign)
+ loadAlign = TD->getABITypeAlignment(LI->getType());
+
bool changed = performCallSlotOptzn(LI,
SI->getPointerOperand()->stripPointerCasts(),
LI->getPointerOperand()->stripPointerCasts(),
- TD->getTypeStoreSize(SI->getOperand(0)->getType()), C);
+ TD->getTypeStoreSize(SI->getOperand(0)->getType()),
+ std::min(storeAlign, loadAlign), C);
if (changed) {
MD->removeInstruction(SI);
SI->eraseFromParent();
@@ -559,7 +567,8 @@ bool MemCpyOpt::processMemSet(MemSetInst *MSI, BasicBlock::iterator &BBI) {
/// the call write its result directly into the destination of the memcpy.
bool MemCpyOpt::performCallSlotOptzn(Instruction *cpy,
Value *cpyDest, Value *cpySrc,
- uint64_t cpyLen, CallInst *C) {
+ uint64_t cpyLen, unsigned cpyAlign,
+ CallInst *C) {
// The general transformation to keep in mind is
//
// call @func(..., src, ...)
@@ -625,6 +634,16 @@ bool MemCpyOpt::performCallSlotOptzn(Instruction *cpy,
return false;
}
+ // Check that dest points to memory that is at least as aligned as src.
+ unsigned srcAlign = srcAlloca->getAlignment();
+ if (!srcAlign)
+ srcAlign = TD->getABITypeAlignment(srcAlloca->getAllocatedType());
+ bool isDestSufficientlyAligned = srcAlign <= cpyAlign;
+ // If dest is not aligned enough and we can't increase its alignment then
+ // bail out.
+ if (!isDestSufficientlyAligned && !isa<AllocaInst>(cpyDest))
+ return false;
+
// Check that src is not accessed except via the call and the memcpy. This
// guarantees that it holds only undefined values when passed in (so the final
// memcpy can be dropped), that it is not read or written between the call and
@@ -673,20 +692,26 @@ bool MemCpyOpt::performCallSlotOptzn(Instruction *cpy,
bool changedArgument = false;
for (unsigned i = 0; i < CS.arg_size(); ++i)
if (CS.getArgument(i)->stripPointerCasts() == cpySrc) {
- if (cpySrc->getType() != cpyDest->getType())
- cpyDest = CastInst::CreatePointerCast(cpyDest, cpySrc->getType(),
- cpyDest->getName(), C);
+ Value *Dest = cpySrc->getType() == cpyDest->getType() ? cpyDest
+ : CastInst::CreatePointerCast(cpyDest, cpySrc->getType(),
+ cpyDest->getName(), C);
changedArgument = true;
- if (CS.getArgument(i)->getType() == cpyDest->getType())
- CS.setArgument(i, cpyDest);
+ if (CS.getArgument(i)->getType() == Dest->getType())
+ CS.setArgument(i, Dest);
else
- CS.setArgument(i, CastInst::CreatePointerCast(cpyDest,
- CS.getArgument(i)->getType(), cpyDest->getName(), C));
+ CS.setArgument(i, CastInst::CreatePointerCast(Dest,
+ CS.getArgument(i)->getType(), Dest->getName(), C));
}
if (!changedArgument)
return false;
+ // If the destination wasn't sufficiently aligned then increase its alignment.
+ if (!isDestSufficientlyAligned) {
+ assert(isa<AllocaInst>(cpyDest) && "Can only increase alloca alignment!");
+ cast<AllocaInst>(cpyDest)->setAlignment(srcAlign);
+ }
+
// Drop any cached information about the call, because we may have changed
// its dependence information by changing its parameter.
MD->removeInstruction(C);
@@ -813,7 +838,8 @@ bool MemCpyOpt::processMemCpy(MemCpyInst *M) {
if (DepInfo.isClobber()) {
if (CallInst *C = dyn_cast<CallInst>(DepInfo.getInst())) {
if (performCallSlotOptzn(M, M->getDest(), M->getSource(),
- CopySize->getZExtValue(), C)) {
+ CopySize->getZExtValue(), M->getAlignment(),
+ C)) {
MD->removeInstruction(M);
M->eraseFromParent();
return true;
@@ -974,7 +1000,7 @@ bool MemCpyOpt::iterateOnFunction(Function &F) {
bool MemCpyOpt::runOnFunction(Function &F) {
bool MadeChange = false;
MD = &getAnalysis<MemoryDependenceAnalysis>();
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
TLI = &getAnalysis<TargetLibraryInfo>();
// If we don't have at least memset and memcpy, there is little point of doing
diff --git a/lib/Transforms/Scalar/NaClCcRewrite.cpp b/lib/Transforms/Scalar/NaClCcRewrite.cpp
index 62bf4325dd..705a0c7374 100644
--- a/lib/Transforms/Scalar/NaClCcRewrite.cpp
+++ b/lib/Transforms/Scalar/NaClCcRewrite.cpp
@@ -22,6 +22,7 @@
#include "llvm/Argument.h"
#include "llvm/Attributes.h"
#include "llvm/Constant.h"
+#include "llvm/DataLayout.h"
#include "llvm/Instruction.h"
#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
@@ -31,7 +32,6 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/InstIterator.h"
-#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetLowering.h"
@@ -709,14 +709,14 @@ template<class T> bool CallNeedsRewrite(
Type* pointee = dyn_cast<PointerType>(t)->getElementType();
// param zero is for the return value
- if (ByvalRewriteRules && call->paramHasAttr(i + 1, Attribute::ByVal)) {
+ if (ByvalRewriteRules && call->paramHasAttr(i + 1, Attributes::ByVal)) {
const TypeRewriteRule* rule =
MatchRewriteRules(pointee, ByvalRewriteRules);
if (rule != 0 && RegUseForRewriteRule(rule) <= available) {
return true;
}
} else if (SretRewriteRules &&
- call->paramHasAttr(i + 1, Attribute::StructRet)) {
+ call->paramHasAttr(i + 1, Attributes::StructRet)) {
if (0 != MatchRewriteRules(pointee, SretRewriteRules)) {
return true;
}
@@ -1053,4 +1053,3 @@ INITIALIZE_PASS(NaClCcRewrite, "naclcc", "NaCl CC Rewriter", false, false)
FunctionPass *llvm::createNaClCcRewritePass(const TargetLowering *tli) {
return new NaClCcRewrite(tli);
}
-
diff --git a/lib/Transforms/Scalar/ObjCARC.cpp b/lib/Transforms/Scalar/ObjCARC.cpp
index d83b069b1c..629f9d2ff5 100644
--- a/lib/Transforms/Scalar/ObjCARC.cpp
+++ b/lib/Transforms/Scalar/ObjCARC.cpp
@@ -1788,7 +1788,9 @@ Constant *ObjCARCOpt::getRetainRVCallee(Module *M) {
Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
Type *Params[] = { I8X };
FunctionType *FTy = FunctionType::get(I8X, Params, /*isVarArg=*/false);
- AttrListPtr Attributes = AttrListPtr().addAttr(~0u, Attribute::NoUnwind);
+ Attributes::Builder B;
+ B.addAttribute(Attributes::NoUnwind);
+ AttrListPtr Attributes = AttrListPtr().addAttr(~0u, Attributes::get(B));
RetainRVCallee =
M->getOrInsertFunction("objc_retainAutoreleasedReturnValue", FTy,
Attributes);
@@ -1802,7 +1804,9 @@ Constant *ObjCARCOpt::getAutoreleaseRVCallee(Module *M) {
Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
Type *Params[] = { I8X };
FunctionType *FTy = FunctionType::get(I8X, Params, /*isVarArg=*/false);
- AttrListPtr Attributes = AttrListPtr().addAttr(~0u, Attribute::NoUnwind);
+ Attributes::Builder B;
+ B.addAttribute(Attributes::NoUnwind);
+ AttrListPtr Attributes = AttrListPtr().addAttr(~0u, Attributes::get(B));
AutoreleaseRVCallee =
M->getOrInsertFunction("objc_autoreleaseReturnValue", FTy,
Attributes);
@@ -1814,7 +1818,9 @@ Constant *ObjCARCOpt::getReleaseCallee(Module *M) {
if (!ReleaseCallee) {
LLVMContext &C = M->getContext();
Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) };
- AttrListPtr Attributes = AttrListPtr().addAttr(~0u, Attribute::NoUnwind);
+ Attributes::Builder B;
+ B.addAttribute(Attributes::NoUnwind);
+ AttrListPtr Attributes = AttrListPtr().addAttr(~0u, Attributes::get(B));
ReleaseCallee =
M->getOrInsertFunction(
"objc_release",
@@ -1828,7 +1834,9 @@ Constant *ObjCARCOpt::getRetainCallee(Module *M) {
if (!RetainCallee) {
LLVMContext &C = M->getContext();
Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) };
- AttrListPtr Attributes = AttrListPtr().addAttr(~0u, Attribute::NoUnwind);
+ Attributes::Builder B;
+ B.addAttribute(Attributes::NoUnwind);
+ AttrListPtr Attributes = AttrListPtr().addAttr(~0u, Attributes::get(B));
RetainCallee =
M->getOrInsertFunction(
"objc_retain",
@@ -1857,7 +1865,9 @@ Constant *ObjCARCOpt::getAutoreleaseCallee(Module *M) {
if (!AutoreleaseCallee) {
LLVMContext &C = M->getContext();
Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) };
- AttrListPtr Attributes = AttrListPtr().addAttr(~0u, Attribute::NoUnwind);
+ Attributes::Builder B;
+ B.addAttribute(Attributes::NoUnwind);
+ AttrListPtr Attributes = AttrListPtr().addAttr(~0u, Attributes::get(B));
AutoreleaseCallee =
M->getOrInsertFunction(
"objc_autorelease",
@@ -3830,9 +3840,13 @@ Constant *ObjCARCContract::getStoreStrongCallee(Module *M) {
Type *I8XX = PointerType::getUnqual(I8X);
Type *Params[] = { I8XX, I8X };
+ Attributes::Builder BNoUnwind;
+ BNoUnwind.addAttribute(Attributes::NoUnwind);
+ Attributes::Builder BNoCapture;
+ BNoCapture.addAttribute(Attributes::NoCapture);
AttrListPtr Attributes = AttrListPtr()
- .addAttr(~0u, Attribute::NoUnwind)
- .addAttr(1, Attribute::NoCapture);
+ .addAttr(~0u, Attributes::get(BNoUnwind))
+ .addAttr(1, Attributes::get(BNoCapture));
StoreStrongCallee =
M->getOrInsertFunction(
@@ -3849,7 +3863,9 @@ Constant *ObjCARCContract::getRetainAutoreleaseCallee(Module *M) {
Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
Type *Params[] = { I8X };
FunctionType *FTy = FunctionType::get(I8X, Params, /*isVarArg=*/false);
- AttrListPtr Attributes = AttrListPtr().addAttr(~0u, Attribute::NoUnwind);
+ Attributes::Builder B;
+ B.addAttribute(Attributes::NoUnwind);
+ AttrListPtr Attributes = AttrListPtr().addAttr(~0u, Attributes::get(B));
RetainAutoreleaseCallee =
M->getOrInsertFunction("objc_retainAutorelease", FTy, Attributes);
}
@@ -3862,7 +3878,9 @@ Constant *ObjCARCContract::getRetainAutoreleaseRVCallee(Module *M) {
Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
Type *Params[] = { I8X };
FunctionType *FTy = FunctionType::get(I8X, Params, /*isVarArg=*/false);
- AttrListPtr Attributes = AttrListPtr().addAttr(~0u, Attribute::NoUnwind);
+ Attributes::Builder B;
+ B.addAttribute(Attributes::NoUnwind);
+ AttrListPtr Attributes = AttrListPtr().addAttr(~0u, Attributes::get(B));
RetainAutoreleaseRVCallee =
M->getOrInsertFunction("objc_retainAutoreleaseReturnValue", FTy,
Attributes);
diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp
index 2c39aab5cd..686520e724 100644
--- a/lib/Transforms/Scalar/SCCP.cpp
+++ b/lib/Transforms/Scalar/SCCP.cpp
@@ -26,7 +26,7 @@
#include "llvm/Pass.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Transforms/Utils/Local.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/Debug.h"
@@ -153,7 +153,7 @@ namespace {
/// Constant Propagation.
///
class SCCPSolver : public InstVisitor<SCCPSolver> {
- const TargetData *TD;
+ const DataLayout *TD;
const TargetLibraryInfo *TLI;
SmallPtrSet<BasicBlock*, 8> BBExecutable; // The BBs that are executable.
DenseMap<Value*, LatticeVal> ValueState; // The state each value is in.
@@ -205,7 +205,7 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
typedef std::pair<BasicBlock*, BasicBlock*> Edge;
DenseSet<Edge> KnownFeasibleEdges;
public:
- SCCPSolver(const TargetData *td, const TargetLibraryInfo *tli)
+ SCCPSolver(const DataLayout *td, const TargetLibraryInfo *tli)
: TD(td), TLI(tli) {}
/// MarkBlockExecutable - This method can be used by clients to mark all of
@@ -1564,7 +1564,7 @@ static void DeleteInstructionInBlock(BasicBlock *BB) {
//
bool SCCP::runOnFunction(Function &F) {
DEBUG(dbgs() << "SCCP on function '" << F.getName() << "'\n");
- const TargetData *TD = getAnalysisIfAvailable<TargetData>();
+ const DataLayout *TD = getAnalysisIfAvailable<DataLayout>();
const TargetLibraryInfo *TLI = &getAnalysis<TargetLibraryInfo>();
SCCPSolver Solver(TD, TLI);
@@ -1693,7 +1693,7 @@ static bool AddressIsTaken(const GlobalValue *GV) {
}
bool IPSCCP::runOnModule(Module &M) {
- const TargetData *TD = getAnalysisIfAvailable<TargetData>();
+ const DataLayout *TD = getAnalysisIfAvailable<DataLayout>();
const TargetLibraryInfo *TLI = &getAnalysis<TargetLibraryInfo>();
SCCPSolver Solver(TD, TLI);
diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp
index a8dc0533bf..ca76251492 100644
--- a/lib/Transforms/Scalar/SROA.cpp
+++ b/lib/Transforms/Scalar/SROA.cpp
@@ -30,7 +30,6 @@
#include "llvm/DebugInfo.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
-#include "llvm/GlobalVariable.h"
#include "llvm/IRBuilder.h"
#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
@@ -42,20 +41,17 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/Support/CallSite.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
#include "llvm/Transforms/Utils/SSAUpdater.h"
@@ -141,6 +137,23 @@ public:
/// splittable and eagerly split them into scalar values.
bool IsSplittable;
+ /// \brief Test whether a partition has been marked as dead.
+ bool isDead() const {
+ if (BeginOffset == UINT64_MAX) {
+ assert(EndOffset == UINT64_MAX);
+ return true;
+ }
+ return false;
+ }
+
+ /// \brief Kill a partition.
+ /// This is accomplished by setting both its beginning and end offset to
+ /// the maximum possible value.
+ void kill() {
+ assert(!isDead() && "He's Dead, Jim!");
+ BeginOffset = EndOffset = UINT64_MAX;
+ }
+
Partition() : ByteRange(), IsSplittable() {}
Partition(uint64_t BeginOffset, uint64_t EndOffset, bool IsSplittable)
: ByteRange(BeginOffset, EndOffset), IsSplittable(IsSplittable) {}
@@ -155,23 +168,22 @@ public:
/// memory use itself with a particular partition. As a consequence there is
/// intentionally overlap between various uses of the same partition.
struct PartitionUse : public ByteRange {
- /// \brief The user of this range of the alloca.
- AssertingVH<Instruction> User;
-
- /// \brief The particular pointer value derived from this alloca in use.
- AssertingVH<Instruction> Ptr;
+ /// \brief The use in question. Provides access to both user and used value.
+ ///
+ /// Note that this may be null if the partition use is *dead*, that is, it
+ /// should be ignored.
+ Use *U;
- PartitionUse() : ByteRange(), User(), Ptr() {}
- PartitionUse(uint64_t BeginOffset, uint64_t EndOffset,
- Instruction *User, Instruction *Ptr)
- : ByteRange(BeginOffset, EndOffset), User(User), Ptr(Ptr) {}
+ PartitionUse() : ByteRange(), U() {}
+ PartitionUse(uint64_t BeginOffset, uint64_t EndOffset, Use *U)
+ : ByteRange(BeginOffset, EndOffset), U(U) {}
};
/// \brief Construct a partitioning of a particular alloca.
///
/// Construction does most of the work for partitioning the alloca. This
/// performs the necessary walks of users and builds a partitioning from it.
- AllocaPartitioning(const TargetData &TD, AllocaInst &AI);
+ AllocaPartitioning(const DataLayout &TD, AllocaInst &AI);
/// \brief Test whether a pointer to the allocation escapes our analysis.
///
@@ -202,16 +214,6 @@ public:
use_iterator use_begin(const_iterator I) { return Uses[I - begin()].begin(); }
use_iterator use_end(unsigned Idx) { return Uses[Idx].end(); }
use_iterator use_end(const_iterator I) { return Uses[I - begin()].end(); }
- void use_push_back(unsigned Idx, const PartitionUse &U) {
- Uses[Idx].push_back(U);
- }
- void use_push_back(const_iterator I, const PartitionUse &U) {
- Uses[I - begin()].push_back(U);
- }
- void use_erase(unsigned Idx, use_iterator UI) { Uses[Idx].erase(UI); }
- void use_erase(const_iterator I, use_iterator UI) {
- Uses[I - begin()].erase(UI);
- }
typedef SmallVectorImpl<PartitionUse>::const_iterator const_use_iterator;
const_use_iterator use_begin(unsigned Idx) const { return Uses[Idx].begin(); }
@@ -222,6 +224,22 @@ public:
const_use_iterator use_end(const_iterator I) const {
return Uses[I - begin()].end();
}
+
+ unsigned use_size(unsigned Idx) const { return Uses[Idx].size(); }
+ unsigned use_size(const_iterator I) const { return Uses[I - begin()].size(); }
+ const PartitionUse &getUse(unsigned PIdx, unsigned UIdx) const {
+ return Uses[PIdx][UIdx];
+ }
+ const PartitionUse &getUse(const_iterator I, unsigned UIdx) const {
+ return Uses[I - begin()][UIdx];
+ }
+
+ void use_push_back(unsigned Idx, const PartitionUse &PU) {
+ Uses[Idx].push_back(PU);
+ }
+ void use_push_back(const_iterator I, const PartitionUse &PU) {
+ Uses[I - begin()].push_back(PU);
+ }
/// @}
/// \brief Allow iterating the dead users for this alloca.
@@ -254,8 +272,16 @@ public:
/// correctly represent. We stash extra data to help us untangle this
/// after the partitioning is complete.
struct MemTransferOffsets {
+ /// The destination begin and end offsets when the destination is within
+ /// this alloca. If the end offset is zero the destination is not within
+ /// this alloca.
uint64_t DestBegin, DestEnd;
+
+ /// The source begin and end offsets when the source is within this alloca.
+ /// If the end offset is zero, the source is not within this alloca.
uint64_t SourceBegin, SourceEnd;
+
+ /// Flag for whether an alloca is splittable.
bool IsSplittable;
};
MemTransferOffsets getMemTransferOffsets(MemTransferInst &II) const {
@@ -267,10 +293,9 @@ public:
/// When manipulating PHI nodes or selects, they can use more than one
/// partition of an alloca. We store a special mapping to allow finding the
/// partition referenced by each of these operands, if any.
- iterator findPartitionForPHIOrSelectOperand(Instruction &I, Value *Op) {
- SmallDenseMap<std::pair<Instruction *, Value *>,
- std::pair<unsigned, unsigned> >::const_iterator MapIt
- = PHIOrSelectOpMap.find(std::make_pair(&I, Op));
+ iterator findPartitionForPHIOrSelectOperand(Use *U) {
+ SmallDenseMap<Use *, std::pair<unsigned, unsigned> >::const_iterator MapIt
+ = PHIOrSelectOpMap.find(U);
if (MapIt == PHIOrSelectOpMap.end())
return end();
@@ -282,11 +307,9 @@ public:
///
/// Similar to mapping these operands back to the partitions, this maps
/// directly to the use structure of that partition.
- use_iterator findPartitionUseForPHIOrSelectOperand(Instruction &I,
- Value *Op) {
- SmallDenseMap<std::pair<Instruction *, Value *>,
- std::pair<unsigned, unsigned> >::const_iterator MapIt
- = PHIOrSelectOpMap.find(std::make_pair(&I, Op));
+ use_iterator findPartitionUseForPHIOrSelectOperand(Use *U) {
+ SmallDenseMap<Use *, std::pair<unsigned, unsigned> >::const_iterator MapIt
+ = PHIOrSelectOpMap.find(U);
assert(MapIt != PHIOrSelectOpMap.end());
return Uses[MapIt->second.first].begin() + MapIt->second.second;
}
@@ -373,8 +396,7 @@ private:
SmallDenseMap<Instruction *, std::pair<uint64_t, bool> > PHIOrSelectSizes;
/// \brief Auxiliary information for particular PHI or select operands.
- SmallDenseMap<std::pair<Instruction *, Value *>,
- std::pair<unsigned, unsigned>, 4> PHIOrSelectOpMap;
+ SmallDenseMap<Use *, std::pair<unsigned, unsigned>, 4> PHIOrSelectOpMap;
/// \brief A utility routine called from the constructor.
///
@@ -389,7 +411,7 @@ template <typename DerivedT, typename RetT>
class AllocaPartitioning::BuilderBase
: public InstVisitor<DerivedT, RetT> {
public:
- BuilderBase(const TargetData &TD, AllocaInst &AI, AllocaPartitioning &P)
+ BuilderBase(const DataLayout &TD, AllocaInst &AI, AllocaPartitioning &P)
: TD(TD),
AllocSize(TD.getTypeAllocSize(AI.getAllocatedType())),
P(P) {
@@ -397,10 +419,12 @@ public:
}
protected:
- const TargetData &TD;
+ const DataLayout &TD;
const uint64_t AllocSize;
AllocaPartitioning &P;
+ SmallPtrSet<Use *, 8> VisitedUses;
+
struct OffsetUse {
Use *U;
int64_t Offset;
@@ -412,14 +436,12 @@ protected:
int64_t Offset;
void enqueueUsers(Instruction &I, int64_t UserOffset) {
- SmallPtrSet<User *, 8> UserSet;
for (Value::use_iterator UI = I.use_begin(), UE = I.use_end();
UI != UE; ++UI) {
- if (!UserSet.insert(*UI))
- continue;
-
- OffsetUse OU = { &UI.getUse(), UserOffset };
- Queue.push_back(OU);
+ if (VisitedUses.insert(&UI.getUse())) {
+ OffsetUse OU = { &UI.getUse(), UserOffset };
+ Queue.push_back(OU);
+ }
}
}
@@ -498,7 +520,7 @@ class AllocaPartitioning::PartitionBuilder
SmallDenseMap<Instruction *, unsigned> MemTransferPartitionMap;
public:
- PartitionBuilder(const TargetData &TD, AllocaInst &AI, AllocaPartitioning &P)
+ PartitionBuilder(const DataLayout &TD, AllocaInst &AI, AllocaPartitioning &P)
: BuilderBase<PartitionBuilder, bool>(TD, AI, P) {}
/// \brief Run the builder over the allocation.
@@ -558,14 +580,6 @@ private:
EndOffset = AllocSize;
}
- // See if we can just add a user onto the last slot currently occupied.
- if (!P.Partitions.empty() &&
- P.Partitions.back().BeginOffset == BeginOffset &&
- P.Partitions.back().EndOffset == EndOffset) {
- P.Partitions.back().IsSplittable &= IsSplittable;
- return;
- }
-
Partition New(BeginOffset, EndOffset, IsSplittable);
P.Partitions.push_back(New);
}
@@ -646,33 +660,57 @@ private:
// Only intrinsics with a constant length can be split.
Offsets.IsSplittable = Length;
- if (*U != II.getRawDest()) {
- assert(*U == II.getRawSource());
- Offsets.SourceBegin = Offset;
- Offsets.SourceEnd = Offset + Size;
- } else {
+ if (*U == II.getRawDest()) {
Offsets.DestBegin = Offset;
Offsets.DestEnd = Offset + Size;
}
+ if (*U == II.getRawSource()) {
+ Offsets.SourceBegin = Offset;
+ Offsets.SourceEnd = Offset + Size;
+ }
- insertUse(II, Offset, Size, Offsets.IsSplittable);
- unsigned NewIdx = P.Partitions.size() - 1;
-
- SmallDenseMap<Instruction *, unsigned>::const_iterator PMI;
- bool Inserted = false;
- llvm::tie(PMI, Inserted)
- = MemTransferPartitionMap.insert(std::make_pair(&II, NewIdx));
- if (Offsets.IsSplittable &&
- (!Inserted || II.getRawSource() == II.getRawDest())) {
- // We've found a memory transfer intrinsic which refers to the alloca as
- // both a source and dest. This is detected either by direct equality of
- // the operand values, or when we visit the intrinsic twice due to two
- // different chains of values leading to it. We refuse to split these to
- // simplify splitting logic. If possible, SROA will still split them into
- // separate allocas and then re-analyze.
+ // If we have set up end offsets for both the source and the destination,
+ // we have found both sides of this transfer pointing at the same alloca.
+ bool SeenBothEnds = Offsets.SourceEnd && Offsets.DestEnd;
+ if (SeenBothEnds && II.getRawDest() != II.getRawSource()) {
+ unsigned PrevIdx = MemTransferPartitionMap[&II];
+
+ // Check if the begin offsets match and this is a non-volatile transfer.
+ // In that case, we can completely elide the transfer.
+ if (!II.isVolatile() && Offsets.SourceBegin == Offsets.DestBegin) {
+ P.Partitions[PrevIdx].kill();
+ return true;
+ }
+
+ // Otherwise we have an offset transfer within the same alloca. We can't
+ // split those.
+ P.Partitions[PrevIdx].IsSplittable = Offsets.IsSplittable = false;
+ } else if (SeenBothEnds) {
+ // Handle the case where this exact use provides both ends of the
+ // operation.
+ assert(II.getRawDest() == II.getRawSource());
+
+ // For non-volatile transfers this is a no-op.
+ if (!II.isVolatile())
+ return true;
+
+ // Otherwise just suppress splitting.
Offsets.IsSplittable = false;
- P.Partitions[PMI->second].IsSplittable = false;
- P.Partitions[NewIdx].IsSplittable = false;
+ }
+
+
+ // Insert the use now that we've fixed up the splittable nature.
+ insertUse(II, Offset, Size, Offsets.IsSplittable);
+
+ // Setup the mapping from intrinsic to partition of we've not seen both
+ // ends of this transfer.
+ if (!SeenBothEnds) {
+ unsigned NewIdx = P.Partitions.size() - 1;
+ bool Inserted
+ = MemTransferPartitionMap.insert(std::make_pair(&II, NewIdx)).second;
+ assert(Inserted &&
+ "Already have intrinsic in map but haven't seen both ends");
+ (void)Inserted;
}
return true;
@@ -811,7 +849,7 @@ class AllocaPartitioning::UseBuilder : public BuilderBase<UseBuilder> {
SmallPtrSet<Instruction *, 4> VisitedDeadInsts;
public:
- UseBuilder(const TargetData &TD, AllocaInst &AI, AllocaPartitioning &P)
+ UseBuilder(const DataLayout &TD, AllocaInst &AI, AllocaPartitioning &P)
: BuilderBase<UseBuilder>(TD, AI, P) {}
/// \brief Run the builder over the allocation.
@@ -858,12 +896,11 @@ private:
B = llvm::prior(B);
for (iterator I = B, E = P.end(); I != E && I->BeginOffset < EndOffset;
++I) {
- PartitionUse NewUse(std::max(I->BeginOffset, BeginOffset),
- std::min(I->EndOffset, EndOffset),
- &User, cast<Instruction>(*U));
- P.use_push_back(I, NewUse);
+ PartitionUse NewPU(std::max(I->BeginOffset, BeginOffset),
+ std::min(I->EndOffset, EndOffset), U);
+ P.use_push_back(I, NewPU);
if (isa<PHINode>(U->getUser()) || isa<SelectInst>(U->getUser()))
- P.PHIOrSelectOpMap[std::make_pair(&User, U->get())]
+ P.PHIOrSelectOpMap[U]
= std::make_pair(I - P.begin(), P.Uses[I - P.begin()].size() - 1);
}
}
@@ -917,6 +954,14 @@ private:
void visitMemTransferInst(MemTransferInst &II) {
ConstantInt *Length = dyn_cast<ConstantInt>(II.getLength());
uint64_t Size = Length ? Length->getZExtValue() : AllocSize - Offset;
+ if (!Size)
+ return markAsDead(II);
+
+ MemTransferOffsets &Offsets = P.MemTransferInstData[&II];
+ if (!II.isVolatile() && Offsets.DestEnd && Offsets.SourceEnd &&
+ Offsets.DestBegin == Offsets.SourceBegin)
+ return markAsDead(II); // Skip identity transfers without side-effects.
+
insertUse(II, Offset, Size);
}
@@ -1015,7 +1060,7 @@ void AllocaPartitioning::splitAndMergePartitions() {
SplitEndOffset = std::max(SplitEndOffset, Partitions[j].EndOffset);
}
- Partitions[j].BeginOffset = Partitions[j].EndOffset = UINT64_MAX;
+ Partitions[j].kill();
++NumDeadPartitions;
++j;
}
@@ -1036,7 +1081,7 @@ void AllocaPartitioning::splitAndMergePartitions() {
if (New.BeginOffset != New.EndOffset)
Partitions.push_back(New);
// Mark the old one for removal.
- Partitions[i].BeginOffset = Partitions[i].EndOffset = UINT64_MAX;
+ Partitions[i].kill();
++NumDeadPartitions;
}
@@ -1063,15 +1108,14 @@ void AllocaPartitioning::splitAndMergePartitions() {
// replaced in the process.
std::sort(Partitions.begin(), Partitions.end());
if (NumDeadPartitions) {
- assert(Partitions.back().BeginOffset == UINT64_MAX);
- assert(Partitions.back().EndOffset == UINT64_MAX);
+ assert(Partitions.back().isDead());
assert((ptrdiff_t)NumDeadPartitions ==
std::count(Partitions.begin(), Partitions.end(), Partitions.back()));
}
Partitions.erase(Partitions.end() - NumDeadPartitions, Partitions.end());
}
-AllocaPartitioning::AllocaPartitioning(const TargetData &TD, AllocaInst &AI)
+AllocaPartitioning::AllocaPartitioning(const DataLayout &TD, AllocaInst &AI)
:
#ifndef NDEBUG
AI(AI),
@@ -1081,11 +1125,15 @@ AllocaPartitioning::AllocaPartitioning(const TargetData &TD, AllocaInst &AI)
if (!PB())
return;
- if (Partitions.size() > 1) {
- // Sort the uses. This arranges for the offsets to be in ascending order,
- // and the sizes to be in descending order.
- std::sort(Partitions.begin(), Partitions.end());
+ // Sort the uses. This arranges for the offsets to be in ascending order,
+ // and the sizes to be in descending order.
+ std::sort(Partitions.begin(), Partitions.end());
+
+ // Remove any partitions from the back which are marked as dead.
+ while (!Partitions.empty() && Partitions.back().isDead())
+ Partitions.pop_back();
+ if (Partitions.size() > 1) {
// Intersect splittability for all partitions with equal offsets and sizes.
// Then remove all but the first so that we have a sequence of non-equal but
// potentially overlapping partitions.
@@ -1115,22 +1163,18 @@ AllocaPartitioning::AllocaPartitioning(const TargetData &TD, AllocaInst &AI)
Type *AllocaPartitioning::getCommonType(iterator I) const {
Type *Ty = 0;
for (const_use_iterator UI = use_begin(I), UE = use_end(I); UI != UE; ++UI) {
- if (isa<IntrinsicInst>(*UI->User))
+ if (!UI->U)
+ continue; // Skip dead uses.
+ if (isa<IntrinsicInst>(*UI->U->getUser()))
continue;
if (UI->BeginOffset != I->BeginOffset || UI->EndOffset != I->EndOffset)
continue;
Type *UserTy = 0;
- if (LoadInst *LI = dyn_cast<LoadInst>(&*UI->User)) {
+ if (LoadInst *LI = dyn_cast<LoadInst>(UI->U->getUser())) {
UserTy = LI->getType();
- } else if (StoreInst *SI = dyn_cast<StoreInst>(&*UI->User)) {
+ } else if (StoreInst *SI = dyn_cast<StoreInst>(UI->U->getUser())) {
UserTy = SI->getValueOperand()->getType();
- } else if (SelectInst *SI = dyn_cast<SelectInst>(&*UI->User)) {
- if (PointerType *PtrTy = dyn_cast<PointerType>(SI->getType()))
- UserTy = PtrTy->getElementType();
- } else if (PHINode *PN = dyn_cast<PHINode>(&*UI->User)) {
- if (PointerType *PtrTy = dyn_cast<PointerType>(PN->getType()))
- UserTy = PtrTy->getElementType();
}
if (Ty && Ty != UserTy)
@@ -1156,9 +1200,11 @@ void AllocaPartitioning::printUsers(raw_ostream &OS, const_iterator I,
StringRef Indent) const {
for (const_use_iterator UI = use_begin(I), UE = use_end(I);
UI != UE; ++UI) {
+ if (!UI->U)
+ continue; // Skip dead uses.
OS << Indent << " [" << UI->BeginOffset << "," << UI->EndOffset << ") "
- << "used by: " << *UI->User << "\n";
- if (MemTransferInst *II = dyn_cast<MemTransferInst>(&*UI->User)) {
+ << "used by: " << *UI->U->getUser() << "\n";
+ if (MemTransferInst *II = dyn_cast<MemTransferInst>(UI->U->getUser())) {
const MemTransferOffsets &MTO = MemTransferInstData.lookup(II);
bool IsDest;
if (!MTO.IsSplittable)
@@ -1301,7 +1347,7 @@ class SROA : public FunctionPass {
const bool RequiresDomTree;
LLVMContext *C;
- const TargetData *TD;
+ const DataLayout *TD;
DominatorTree *DT;
/// \brief Worklist of alloca instructions to simplify.
@@ -1322,6 +1368,16 @@ class SROA : public FunctionPass {
/// uses as dead. Only used to guard insertion into DeadInsts.
SmallPtrSet<Instruction *, 4> DeadSplitInsts;
+ /// \brief Post-promotion worklist.
+ ///
+ /// Sometimes we discover an alloca which has a high probability of becoming
+ /// viable for SROA after a round of promotion takes place. In those cases,
+ /// the alloca is enqueued here for re-processing.
+ ///
+ /// Note that we have to be very careful to clear allocas out of this list in
+ /// the event they are deleted.
+ SetVector<AllocaInst *, SmallVector<AllocaInst *, 16> > PostPromotionWorklist;
+
/// \brief A collection of alloca instructions we can directly promote.
std::vector<AllocaInst *> PromotableAllocas;
@@ -1338,6 +1394,7 @@ public:
static char ID;
private:
+ friend class PHIOrSelectSpeculator;
friend class AllocaPartitionRewriter;
friend class AllocaPartitionVectorRewriter;
@@ -1363,12 +1420,295 @@ INITIALIZE_PASS_DEPENDENCY(DominatorTree)
INITIALIZE_PASS_END(SROA, "sroa", "Scalar Replacement Of Aggregates",
false, false)
+namespace {
+/// \brief Visitor to speculate PHIs and Selects where possible.
+class PHIOrSelectSpeculator : public InstVisitor<PHIOrSelectSpeculator> {
+ // Befriend the base class so it can delegate to private visit methods.
+ friend class llvm::InstVisitor<PHIOrSelectSpeculator>;
+
+ const DataLayout &TD;
+ AllocaPartitioning &P;
+ SROA &Pass;
+
+public:
+ PHIOrSelectSpeculator(const DataLayout &TD, AllocaPartitioning &P, SROA &Pass)
+ : TD(TD), P(P), Pass(Pass) {}
+
+ /// \brief Visit the users of an alloca partition and rewrite them.
+ void visitUsers(AllocaPartitioning::const_iterator PI) {
+ // Note that we need to use an index here as the underlying vector of uses
+ // may be grown during speculation. However, we never need to re-visit the
+ // new uses, and so we can use the initial size bound.
+ for (unsigned Idx = 0, Size = P.use_size(PI); Idx != Size; ++Idx) {
+ const AllocaPartitioning::PartitionUse &PU = P.getUse(PI, Idx);
+ if (!PU.U)
+ continue; // Skip dead use.
+
+ visit(cast<Instruction>(PU.U->getUser()));
+ }
+ }
+
+private:
+ // By default, skip this instruction.
+ void visitInstruction(Instruction &I) {}
+
+ /// PHI instructions that use an alloca and are subsequently loaded can be
+ /// rewritten to load both input pointers in the pred blocks and then PHI the
+ /// results, allowing the load of the alloca to be promoted.
+ /// From this:
+ /// %P2 = phi [i32* %Alloca, i32* %Other]
+ /// %V = load i32* %P2
+ /// to:
+ /// %V1 = load i32* %Alloca -> will be mem2reg'd
+ /// ...
+ /// %V2 = load i32* %Other
+ /// ...
+ /// %V = phi [i32 %V1, i32 %V2]
+ ///
+ /// We can do this to a select if its only uses are loads and if the operands
+ /// to the select can be loaded unconditionally.
+ ///
+ /// FIXME: This should be hoisted into a generic utility, likely in
+ /// Transforms/Util/Local.h
+ bool isSafePHIToSpeculate(PHINode &PN, SmallVectorImpl<LoadInst *> &Loads) {
+ // For now, we can only do this promotion if the load is in the same block
+ // as the PHI, and if there are no stores between the phi and load.
+ // TODO: Allow recursive phi users.
+ // TODO: Allow stores.
+ BasicBlock *BB = PN.getParent();
+ unsigned MaxAlign = 0;
+ for (Value::use_iterator UI = PN.use_begin(), UE = PN.use_end();
+ UI != UE; ++UI) {
+ LoadInst *LI = dyn_cast<LoadInst>(*UI);
+ if (LI == 0 || !LI->isSimple()) return false;
+
+ // For now we only allow loads in the same block as the PHI. This is
+ // a common case that happens when instcombine merges two loads through
+ // a PHI.
+ if (LI->getParent() != BB) return false;
+
+ // Ensure that there are no instructions between the PHI and the load that
+ // could store.
+ for (BasicBlock::iterator BBI = &PN; &*BBI != LI; ++BBI)
+ if (BBI->mayWriteToMemory())
+ return false;
+
+ MaxAlign = std::max(MaxAlign, LI->getAlignment());
+ Loads.push_back(LI);
+ }
+
+ // We can only transform this if it is safe to push the loads into the
+ // predecessor blocks. The only thing to watch out for is that we can't put
+ // a possibly trapping load in the predecessor if it is a critical edge.
+ for (unsigned Idx = 0, Num = PN.getNumIncomingValues(); Idx != Num;
+ ++Idx) {
+ TerminatorInst *TI = PN.getIncomingBlock(Idx)->getTerminator();
+ Value *InVal = PN.getIncomingValue(Idx);
+
+ // If the value is produced by the terminator of the predecessor (an
+ // invoke) or it has side-effects, there is no valid place to put a load
+ // in the predecessor.
+ if (TI == InVal || TI->mayHaveSideEffects())
+ return false;
+
+ // If the predecessor has a single successor, then the edge isn't
+ // critical.
+ if (TI->getNumSuccessors() == 1)
+ continue;
+
+ // If this pointer is always safe to load, or if we can prove that there
+ // is already a load in the block, then we can move the load to the pred
+ // block.
+ if (InVal->isDereferenceablePointer() ||
+ isSafeToLoadUnconditionally(InVal, TI, MaxAlign, &TD))
+ continue;
+
+ return false;
+ }
+
+ return true;
+ }
+
+ void visitPHINode(PHINode &PN) {
+ DEBUG(dbgs() << " original: " << PN << "\n");
+
+ SmallVector<LoadInst *, 4> Loads;
+ if (!isSafePHIToSpeculate(PN, Loads))
+ return;
+
+ assert(!Loads.empty());
+
+ Type *LoadTy = cast<PointerType>(PN.getType())->getElementType();
+ IRBuilder<> PHIBuilder(&PN);
+ PHINode *NewPN = PHIBuilder.CreatePHI(LoadTy, PN.getNumIncomingValues(),
+ PN.getName() + ".sroa.speculated");
+
+ // Get the TBAA tag and alignment to use from one of the loads. It doesn't
+ // matter which one we get and if any differ, it doesn't matter.
+ LoadInst *SomeLoad = cast<LoadInst>(Loads.back());
+ MDNode *TBAATag = SomeLoad->getMetadata(LLVMContext::MD_tbaa);
+ unsigned Align = SomeLoad->getAlignment();
+
+ // Rewrite all loads of the PN to use the new PHI.
+ do {
+ LoadInst *LI = Loads.pop_back_val();
+ LI->replaceAllUsesWith(NewPN);
+ Pass.DeadInsts.push_back(LI);
+ } while (!Loads.empty());
+
+ // Inject loads into all of the pred blocks.
+ for (unsigned Idx = 0, Num = PN.getNumIncomingValues(); Idx != Num; ++Idx) {
+ BasicBlock *Pred = PN.getIncomingBlock(Idx);
+ TerminatorInst *TI = Pred->getTerminator();
+ Use *InUse = &PN.getOperandUse(PN.getOperandNumForIncomingValue(Idx));
+ Value *InVal = PN.getIncomingValue(Idx);
+ IRBuilder<> PredBuilder(TI);
+
+ LoadInst *Load
+ = PredBuilder.CreateLoad(InVal, (PN.getName() + ".sroa.speculate.load." +
+ Pred->getName()));
+ ++NumLoadsSpeculated;
+ Load->setAlignment(Align);
+ if (TBAATag)
+ Load->setMetadata(LLVMContext::MD_tbaa, TBAATag);
+ NewPN->addIncoming(Load, Pred);
+
+ Instruction *Ptr = dyn_cast<Instruction>(InVal);
+ if (!Ptr)
+ // No uses to rewrite.
+ continue;
+
+ // Try to lookup and rewrite any partition uses corresponding to this phi
+ // input.
+ AllocaPartitioning::iterator PI
+ = P.findPartitionForPHIOrSelectOperand(InUse);
+ if (PI == P.end())
+ continue;
+
+ // Replace the Use in the PartitionUse for this operand with the Use
+ // inside the load.
+ AllocaPartitioning::use_iterator UI
+ = P.findPartitionUseForPHIOrSelectOperand(InUse);
+ assert(isa<PHINode>(*UI->U->getUser()));
+ UI->U = &Load->getOperandUse(Load->getPointerOperandIndex());
+ }
+ DEBUG(dbgs() << " speculated to: " << *NewPN << "\n");
+ }
+
+ /// Select instructions that use an alloca and are subsequently loaded can be
+ /// rewritten to load both input pointers and then select between the result,
+ /// allowing the load of the alloca to be promoted.
+ /// From this:
+ /// %P2 = select i1 %cond, i32* %Alloca, i32* %Other
+ /// %V = load i32* %P2
+ /// to:
+ /// %V1 = load i32* %Alloca -> will be mem2reg'd
+ /// %V2 = load i32* %Other
+ /// %V = select i1 %cond, i32 %V1, i32 %V2
+ ///
+ /// We can do this to a select if its only uses are loads and if the operand
+ /// to the select can be loaded unconditionally.
+ bool isSafeSelectToSpeculate(SelectInst &SI,
+ SmallVectorImpl<LoadInst *> &Loads) {
+ Value *TValue = SI.getTrueValue();
+ Value *FValue = SI.getFalseValue();
+ bool TDerefable = TValue->isDereferenceablePointer();
+ bool FDerefable = FValue->isDereferenceablePointer();
+
+ for (Value::use_iterator UI = SI.use_begin(), UE = SI.use_end();
+ UI != UE; ++UI) {
+ LoadInst *LI = dyn_cast<LoadInst>(*UI);
+ if (LI == 0 || !LI->isSimple()) return false;
+
+ // Both operands to the select need to be dereferencable, either
+ // absolutely (e.g. allocas) or at this point because we can see other
+ // accesses to it.
+ if (!TDerefable && !isSafeToLoadUnconditionally(TValue, LI,
+ LI->getAlignment(), &TD))
+ return false;
+ if (!FDerefable && !isSafeToLoadUnconditionally(FValue, LI,
+ LI->getAlignment(), &TD))
+ return false;
+ Loads.push_back(LI);
+ }
+
+ return true;
+ }
+
+ void visitSelectInst(SelectInst &SI) {
+ DEBUG(dbgs() << " original: " << SI << "\n");
+ IRBuilder<> IRB(&SI);
+
+ // If the select isn't safe to speculate, just use simple logic to emit it.
+ SmallVector<LoadInst *, 4> Loads;
+ if (!isSafeSelectToSpeculate(SI, Loads))
+ return;
+
+ Use *Ops[2] = { &SI.getOperandUse(1), &SI.getOperandUse(2) };
+ AllocaPartitioning::iterator PIs[2];
+ AllocaPartitioning::PartitionUse PUs[2];
+ for (unsigned i = 0, e = 2; i != e; ++i) {
+ PIs[i] = P.findPartitionForPHIOrSelectOperand(Ops[i]);
+ if (PIs[i] != P.end()) {
+ // If the pointer is within the partitioning, remove the select from
+ // its uses. We'll add in the new loads below.
+ AllocaPartitioning::use_iterator UI
+ = P.findPartitionUseForPHIOrSelectOperand(Ops[i]);
+ PUs[i] = *UI;
+ // Clear out the use here so that the offsets into the use list remain
+ // stable but this use is ignored when rewriting.
+ UI->U = 0;
+ }
+ }
+
+ Value *TV = SI.getTrueValue();
+ Value *FV = SI.getFalseValue();
+ // Replace the loads of the select with a select of two loads.
+ while (!Loads.empty()) {
+ LoadInst *LI = Loads.pop_back_val();
+
+ IRB.SetInsertPoint(LI);
+ LoadInst *TL =
+ IRB.CreateLoad(TV, LI->getName() + ".sroa.speculate.load.true");
+ LoadInst *FL =
+ IRB.CreateLoad(FV, LI->getName() + ".sroa.speculate.load.false");
+ NumLoadsSpeculated += 2;
+
+ // Transfer alignment and TBAA info if present.
+ TL->setAlignment(LI->getAlignment());
+ FL->setAlignment(LI->getAlignment());
+ if (MDNode *Tag = LI->getMetadata(LLVMContext::MD_tbaa)) {
+ TL->setMetadata(LLVMContext::MD_tbaa, Tag);
+ FL->setMetadata(LLVMContext::MD_tbaa, Tag);
+ }
+
+ Value *V = IRB.CreateSelect(SI.getCondition(), TL, FL,
+ LI->getName() + ".sroa.speculated");
+
+ LoadInst *Loads[2] = { TL, FL };
+ for (unsigned i = 0, e = 2; i != e; ++i) {
+ if (PIs[i] != P.end()) {
+ Use *LoadUse = &Loads[i]->getOperandUse(0);
+ assert(PUs[i].U->get() == LoadUse->get());
+ PUs[i].U = LoadUse;
+ P.use_push_back(PIs[i], PUs[i]);
+ }
+ }
+
+ DEBUG(dbgs() << " speculated to: " << *V << "\n");
+ LI->replaceAllUsesWith(V);
+ Pass.DeadInsts.push_back(LI);
+ }
+ }
+};
+}
+
/// \brief Accumulate the constant offsets in a GEP into a single APInt offset.
///
/// If the provided GEP is all-constant, the total byte offset formed by the
/// GEP is computed and Offset is set to it. If the GEP has any non-constant
/// operands, the function returns false and the value of Offset is unmodified.
-static bool accumulateGEPOffsets(const TargetData &TD, GEPOperator &GEP,
+static bool accumulateGEPOffsets(const DataLayout &TD, GEPOperator &GEP,
APInt &Offset) {
APInt GEPOffset(Offset.getBitWidth(), 0);
for (gep_type_iterator GTI = gep_type_begin(GEP), GTE = gep_type_end(GEP);
@@ -1428,7 +1768,7 @@ static Value *buildGEP(IRBuilder<> &IRB, Value *BasePtr,
/// TargetTy. If we can't find one with the same type, we at least try to use
/// one with the same size. If none of that works, we just produce the GEP as
/// indicated by Indices to have the correct offset.
-static Value *getNaturalGEPWithType(IRBuilder<> &IRB, const TargetData &TD,
+static Value *getNaturalGEPWithType(IRBuilder<> &IRB, const DataLayout &TD,
Value *BasePtr, Type *Ty, Type *TargetTy,
SmallVectorImpl<Value *> &Indices,
const Twine &Prefix) {
@@ -1446,6 +1786,8 @@ static Value *getNaturalGEPWithType(IRBuilder<> &IRB, const TargetData &TD,
ElementTy = SeqTy->getElementType();
Indices.push_back(IRB.getInt(APInt(TD.getPointerSizeInBits(), 0)));
} else if (StructType *STy = dyn_cast<StructType>(ElementTy)) {
+ if (STy->element_begin() == STy->element_end())
+ break; // Nothing left to descend into.
ElementTy = *STy->element_begin();
Indices.push_back(IRB.getInt32(0));
} else {
@@ -1463,7 +1805,7 @@ static Value *getNaturalGEPWithType(IRBuilder<> &IRB, const TargetData &TD,
///
/// This is the recursive step for getNaturalGEPWithOffset that walks down the
/// element types adding appropriate indices for the GEP.
-static Value *getNaturalGEPRecursively(IRBuilder<> &IRB, const TargetData &TD,
+static Value *getNaturalGEPRecursively(IRBuilder<> &IRB, const DataLayout &TD,
Value *Ptr, Type *Ty, APInt &Offset,
Type *TargetTy,
SmallVectorImpl<Value *> &Indices,
@@ -1534,7 +1876,7 @@ static Value *getNaturalGEPRecursively(IRBuilder<> &IRB, const TargetData &TD,
/// Indices, and setting Ty to the result subtype.
///
/// If no natural GEP can be constructed, this function returns null.
-static Value *getNaturalGEPWithOffset(IRBuilder<> &IRB, const TargetData &TD,
+static Value *getNaturalGEPWithOffset(IRBuilder<> &IRB, const DataLayout &TD,
Value *Ptr, APInt Offset, Type *TargetTy,
SmallVectorImpl<Value *> &Indices,
const Twine &Prefix) {
@@ -1574,7 +1916,7 @@ static Value *getNaturalGEPWithOffset(IRBuilder<> &IRB, const TargetData &TD,
/// properities. The algorithm tries to fold as many constant indices into
/// a single GEP as possible, thus making each GEP more independent of the
/// surrounding code.
-static Value *getAdjustedPtr(IRBuilder<> &IRB, const TargetData &TD,
+static Value *getAdjustedPtr(IRBuilder<> &IRB, const DataLayout &TD,
Value *Ptr, APInt Offset, Type *PointerTy,
const Twine &Prefix) {
// Even though we don't look through PHI nodes, we could be called on an
@@ -1670,7 +2012,7 @@ static Value *getAdjustedPtr(IRBuilder<> &IRB, const TargetData &TD,
/// SSA value. We only can ensure this for a limited set of operations, and we
/// don't want to do the rewrites unless we are confident that the result will
/// be promotable, so we have an early test here.
-static bool isVectorPromotionViable(const TargetData &TD,
+static bool isVectorPromotionViable(const DataLayout &TD,
Type *AllocaTy,
AllocaPartitioning &P,
uint64_t PartitionBeginOffset,
@@ -1693,6 +2035,9 @@ static bool isVectorPromotionViable(const TargetData &TD,
ElementSize /= 8;
for (; I != E; ++I) {
+ if (!I->U)
+ continue; // Skip dead use.
+
uint64_t BeginOffset = I->BeginOffset - PartitionBeginOffset;
uint64_t BeginIndex = BeginOffset / ElementSize;
if (BeginIndex * ElementSize != BeginOffset ||
@@ -1710,19 +2055,20 @@ static bool isVectorPromotionViable(const TargetData &TD,
(EndOffset - BeginOffset) != VecSize)
return false;
- if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&*I->User)) {
+ if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I->U->getUser())) {
if (MI->isVolatile())
return false;
- if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(&*I->User)) {
+ if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(I->U->getUser())) {
const AllocaPartitioning::MemTransferOffsets &MTO
= P.getMemTransferOffsets(*MTI);
if (!MTO.IsSplittable)
return false;
}
- } else if (I->Ptr->getType()->getPointerElementType()->isStructTy()) {
+ } else if (I->U->get()->getType()->getPointerElementType()->isStructTy()) {
// Disable vector promotion when there are loads or stores of an FCA.
return false;
- } else if (!isa<LoadInst>(*I->User) && !isa<StoreInst>(*I->User)) {
+ } else if (!isa<LoadInst>(I->U->getUser()) &&
+ !isa<StoreInst>(I->U->getUser())) {
return false;
}
}
@@ -1736,13 +2082,14 @@ static bool isVectorPromotionViable(const TargetData &TD,
/// promotion to an SSA value. We only can ensure this for a limited set of
/// operations, and we don't want to do the rewrites unless we are confident
/// that the result will be promotable, so we have an early test here.
-static bool isIntegerPromotionViable(const TargetData &TD,
+static bool isIntegerPromotionViable(const DataLayout &TD,
Type *AllocaTy,
+ uint64_t AllocBeginOffset,
AllocaPartitioning &P,
AllocaPartitioning::const_use_iterator I,
AllocaPartitioning::const_use_iterator E) {
IntegerType *Ty = dyn_cast<IntegerType>(AllocaTy);
- if (!Ty)
+ if (!Ty || 8*TD.getTypeStoreSize(Ty) != Ty->getBitWidth())
return false;
// Check the uses to ensure the uses are (likely) promoteable integer uses.
@@ -1751,20 +2098,28 @@ static bool isIntegerPromotionViable(const TargetData &TD,
// splittable later) and lose the ability to promote each element access.
bool WholeAllocaOp = false;
for (; I != E; ++I) {
- if (LoadInst *LI = dyn_cast<LoadInst>(&*I->User)) {
+ if (!I->U)
+ continue; // Skip dead use.
+
+ // We can't reasonably handle cases where the load or store extends past
+ // the end of the aloca's type and into its padding.
+ if ((I->EndOffset - AllocBeginOffset) > TD.getTypeStoreSize(Ty))
+ return false;
+
+ if (LoadInst *LI = dyn_cast<LoadInst>(I->U->getUser())) {
if (LI->isVolatile() || !LI->getType()->isIntegerTy())
return false;
if (LI->getType() == Ty)
WholeAllocaOp = true;
- } else if (StoreInst *SI = dyn_cast<StoreInst>(&*I->User)) {
+ } else if (StoreInst *SI = dyn_cast<StoreInst>(I->U->getUser())) {
if (SI->isVolatile() || !SI->getValueOperand()->getType()->isIntegerTy())
return false;
if (SI->getValueOperand()->getType() == Ty)
WholeAllocaOp = true;
- } else if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&*I->User)) {
+ } else if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I->U->getUser())) {
if (MI->isVolatile())
return false;
- if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(&*I->User)) {
+ if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(I->U->getUser())) {
const AllocaPartitioning::MemTransferOffsets &MTO
= P.getMemTransferOffsets(*MTI);
if (!MTO.IsSplittable)
@@ -1789,7 +2144,7 @@ class AllocaPartitionRewriter : public InstVisitor<AllocaPartitionRewriter,
// Befriend the base class so it can delegate to private visit methods.
friend class llvm::InstVisitor<AllocaPartitionRewriter, bool>;
- const TargetData &TD;
+ const DataLayout &TD;
AllocaPartitioning &P;
SROA &Pass;
AllocaInst &OldAI, &NewAI;
@@ -1816,13 +2171,14 @@ class AllocaPartitionRewriter : public InstVisitor<AllocaPartitionRewriter,
// The offset of the partition user currently being rewritten.
uint64_t BeginOffset, EndOffset;
+ Use *OldUse;
Instruction *OldPtr;
// The name prefix to use when rewriting instructions for this alloca.
std::string NamePrefix;
public:
- AllocaPartitionRewriter(const TargetData &TD, AllocaPartitioning &P,
+ AllocaPartitionRewriter(const DataLayout &TD, AllocaPartitioning &P,
AllocaPartitioning::iterator PI,
SROA &Pass, AllocaInst &OldAI, AllocaInst &NewAI,
uint64_t NewBeginOffset, uint64_t NewEndOffset)
@@ -1847,16 +2203,19 @@ public:
"Only multiple-of-8 sized vector elements are viable");
ElementSize = VecTy->getScalarSizeInBits() / 8;
} else if (isIntegerPromotionViable(TD, NewAI.getAllocatedType(),
- P, I, E)) {
+ NewAllocaBeginOffset, P, I, E)) {
IntPromotionTy = cast<IntegerType>(NewAI.getAllocatedType());
}
bool CanSROA = true;
for (; I != E; ++I) {
+ if (!I->U)
+ continue; // Skip dead uses.
BeginOffset = I->BeginOffset;
EndOffset = I->EndOffset;
- OldPtr = I->Ptr;
+ OldUse = I->U;
+ OldPtr = cast<Instruction>(I->U->get());
NamePrefix = (Twine(NewAI.getName()) + "." + Twine(BeginOffset)).str();
- CanSROA &= visit(I->User);
+ CanSROA &= visit(cast<Instruction>(I->U->getUser()));
}
if (VecTy) {
assert(CanSROA);
@@ -1884,6 +2243,38 @@ private:
return getAdjustedPtr(IRB, TD, &NewAI, Offset, PointerTy, getName(""));
}
+ /// \brief Compute suitable alignment to access an offset into the new alloca.
+ unsigned getOffsetAlign(uint64_t Offset) {
+ unsigned NewAIAlign = NewAI.getAlignment();
+ if (!NewAIAlign)
+ NewAIAlign = TD.getABITypeAlignment(NewAI.getAllocatedType());
+ return MinAlign(NewAIAlign, Offset);
+ }
+
+ /// \brief Compute suitable alignment to access this partition of the new
+ /// alloca.
+ unsigned getPartitionAlign() {
+ return getOffsetAlign(BeginOffset - NewAllocaBeginOffset);
+ }
+
+ /// \brief Compute suitable alignment to access a type at an offset of the
+ /// new alloca.
+ ///
+ /// \returns zero if the type's ABI alignment is a suitable alignment,
+ /// otherwise returns the maximal suitable alignment.
+ unsigned getOffsetTypeAlign(Type *Ty, uint64_t Offset) {
+ unsigned Align = getOffsetAlign(Offset);
+ return Align == TD.getABITypeAlignment(Ty) ? 0 : Align;
+ }
+
+ /// \brief Compute suitable alignment to access a type at the beginning of
+ /// this partition of the new alloca.
+ ///
+ /// See \c getOffsetTypeAlign for details; this routine delegates to it.
+ unsigned getPartitionTypeAlign(Type *Ty) {
+ return getOffsetTypeAlign(Ty, BeginOffset - NewAllocaBeginOffset);
+ }
+
ConstantInt *getIndex(IRBuilder<> &IRB, uint64_t Offset) {
assert(VecTy && "Can only call getIndex when rewriting a vector");
uint64_t RelOffset = Offset - NewAllocaBeginOffset;
@@ -1900,8 +2291,15 @@ private:
getName(".load"));
assert(Offset >= NewAllocaBeginOffset && "Out of bounds offset");
uint64_t RelOffset = Offset - NewAllocaBeginOffset;
- if (RelOffset)
- V = IRB.CreateLShr(V, RelOffset*8, getName(".shift"));
+ assert(TD.getTypeStoreSize(TargetTy) + RelOffset <=
+ TD.getTypeStoreSize(IntPromotionTy) &&
+ "Element load outside of alloca store");
+ uint64_t ShAmt = 8*RelOffset;
+ if (TD.isBigEndian())
+ ShAmt = 8*(TD.getTypeStoreSize(IntPromotionTy) -
+ TD.getTypeStoreSize(TargetTy) - RelOffset);
+ if (ShAmt)
+ V = IRB.CreateLShr(V, ShAmt, getName(".shift"));
if (TargetTy != IntPromotionTy) {
assert(TargetTy->getBitWidth() < IntPromotionTy->getBitWidth() &&
"Cannot extract to a larger integer!");
@@ -1920,11 +2318,17 @@ private:
V = IRB.CreateZExt(V, IntPromotionTy, getName(".ext"));
assert(Offset >= NewAllocaBeginOffset && "Out of bounds offset");
uint64_t RelOffset = Offset - NewAllocaBeginOffset;
- if (RelOffset)
- V = IRB.CreateShl(V, RelOffset*8, getName(".shift"));
-
- APInt Mask = ~Ty->getMask().zext(IntPromotionTy->getBitWidth())
- .shl(RelOffset*8);
+ assert(TD.getTypeStoreSize(Ty) + RelOffset <=
+ TD.getTypeStoreSize(IntPromotionTy) &&
+ "Element store outside of alloca store");
+ uint64_t ShAmt = 8*RelOffset;
+ if (TD.isBigEndian())
+ ShAmt = 8*(TD.getTypeStoreSize(IntPromotionTy) - TD.getTypeStoreSize(Ty)
+ - RelOffset);
+ if (ShAmt)
+ V = IRB.CreateShl(V, ShAmt, getName(".shift"));
+
+ APInt Mask = ~Ty->getMask().zext(IntPromotionTy->getBitWidth()).shl(ShAmt);
Value *Old = IRB.CreateAnd(IRB.CreateAlignedLoad(&NewAI,
NewAI.getAlignment(),
getName(".oldload")),
@@ -1992,9 +2396,7 @@ private:
Value *NewPtr = getAdjustedAllocaPtr(IRB,
LI.getPointerOperand()->getType());
LI.setOperand(0, NewPtr);
- if (LI.getAlignment())
- LI.setAlignment(MinAlign(NewAI.getAlignment(),
- BeginOffset - NewAllocaBeginOffset));
+ LI.setAlignment(getPartitionTypeAlign(LI.getType()));
DEBUG(dbgs() << " to: " << LI << "\n");
deleteIfTriviallyDead(OldOp);
@@ -2043,12 +2445,17 @@ private:
if (IntPromotionTy)
return rewriteIntegerStore(IRB, SI);
+ // Strip all inbounds GEPs and pointer casts to try to dig out any root
+ // alloca that should be re-examined after promoting this alloca.
+ if (SI.getValueOperand()->getType()->isPointerTy())
+ if (AllocaInst *AI = dyn_cast<AllocaInst>(SI.getValueOperand()
+ ->stripInBoundsOffsets()))
+ Pass.PostPromotionWorklist.insert(AI);
+
Value *NewPtr = getAdjustedAllocaPtr(IRB,
SI.getPointerOperand()->getType());
SI.setOperand(1, NewPtr);
- if (SI.getAlignment())
- SI.setAlignment(MinAlign(NewAI.getAlignment(),
- BeginOffset - NewAllocaBeginOffset));
+ SI.setAlignment(getPartitionTypeAlign(SI.getValueOperand()->getType()));
DEBUG(dbgs() << " to: " << SI << "\n");
deleteIfTriviallyDead(OldOp);
@@ -2064,14 +2471,8 @@ private:
// pointer to the new alloca.
if (!isa<Constant>(II.getLength())) {
II.setDest(getAdjustedAllocaPtr(IRB, II.getRawDest()->getType()));
-
Type *CstTy = II.getAlignmentCst()->getType();
- if (!NewAI.getAlignment())
- II.setAlignment(ConstantInt::get(CstTy, 0));
- else
- II.setAlignment(
- ConstantInt::get(CstTy, MinAlign(NewAI.getAlignment(),
- BeginOffset - NewAllocaBeginOffset)));
+ II.setAlignment(ConstantInt::get(CstTy, getPartitionAlign()));
deleteIfTriviallyDead(OldPtr);
return false;
@@ -2092,15 +2493,10 @@ private:
!TD.isLegalInteger(TD.getTypeSizeInBits(ScalarTy)))) {
Type *SizeTy = II.getLength()->getType();
Constant *Size = ConstantInt::get(SizeTy, EndOffset - BeginOffset);
- unsigned Align = 1;
- if (NewAI.getAlignment())
- Align = MinAlign(NewAI.getAlignment(),
- BeginOffset - NewAllocaBeginOffset);
-
CallInst *New
= IRB.CreateMemSet(getAdjustedAllocaPtr(IRB,
II.getRawDest()->getType()),
- II.getValue(), Size, Align,
+ II.getValue(), Size, getPartitionAlign(),
II.isVolatile());
(void)New;
DEBUG(dbgs() << " to: " << *New << "\n");
@@ -2182,6 +2578,16 @@ private:
const AllocaPartitioning::MemTransferOffsets &MTO
= P.getMemTransferOffsets(II);
+ // Compute the relative offset within the transfer.
+ unsigned IntPtrWidth = TD.getPointerSizeInBits();
+ APInt RelOffset(IntPtrWidth, BeginOffset - (IsDest ? MTO.DestBegin
+ : MTO.SourceBegin));
+
+ unsigned Align = II.getAlignment();
+ if (Align > 1)
+ Align = MinAlign(RelOffset.zextOrTrunc(64).getZExtValue(),
+ MinAlign(II.getAlignment(), getPartitionAlign()));
+
// For unsplit intrinsics, we simply modify the source and destination
// pointers in place. This isn't just an optimization, it is a matter of
// correctness. With unsplit intrinsics we may be dealing with transfers
@@ -2197,11 +2603,7 @@ private:
II.setSource(getAdjustedAllocaPtr(IRB, II.getRawSource()->getType()));
Type *CstTy = II.getAlignmentCst()->getType();
- if (II.getAlignment() > 1)
- II.setAlignment(ConstantInt::get(
- CstTy, MinAlign(II.getAlignment(),
- MinAlign(NewAI.getAlignment(),
- BeginOffset - NewAllocaBeginOffset))));
+ II.setAlignment(ConstantInt::get(CstTy, Align));
DEBUG(dbgs() << " to: " << II << "\n");
deleteIfTriviallyDead(OldOp);
@@ -2213,11 +2615,6 @@ private:
// memmove with memcpy, and we don't need to worry about all manner of
// downsides to splitting and transforming the operations.
- // Compute the relative offset within the transfer.
- unsigned IntPtrWidth = TD.getPointerSizeInBits();
- APInt RelOffset(IntPtrWidth, BeginOffset - (IsDest ? MTO.DestBegin
- : MTO.SourceBegin));
-
// If this doesn't map cleanly onto the alloca type, and that type isn't
// a single value type, just emit a memcpy.
bool EmitMemCpy
@@ -2260,11 +2657,6 @@ private:
OtherPtr = getAdjustedPtr(IRB, TD, OtherPtr, RelOffset, OtherPtrTy,
getName("." + OtherPtr->getName()));
- unsigned Align = II.getAlignment();
- if (Align > 1)
- Align = MinAlign(RelOffset.zextOrTrunc(64).getZExtValue(),
- MinAlign(II.getAlignment(), NewAI.getAlignment()));
-
// Strip all inbounds GEPs and pointer casts to try to dig out any root
// alloca that should be re-examined after rewriting this instruction.
if (AllocaInst *AI
@@ -2286,6 +2678,12 @@ private:
return false;
}
+ // Note that we clamp the alignment to 1 here as a 0 alignment for a memcpy
+ // is equivalent to 1, but that isn't true if we end up rewriting this as
+ // a load or store.
+ if (!Align)
+ Align = 1;
+
Value *SrcPtr = OtherPtr;
Value *DstPtr = &NewAI;
if (!IsDest)
@@ -2343,215 +2741,25 @@ private:
return true;
}
- /// PHI instructions that use an alloca and are subsequently loaded can be
- /// rewritten to load both input pointers in the pred blocks and then PHI the
- /// results, allowing the load of the alloca to be promoted.
- /// From this:
- /// %P2 = phi [i32* %Alloca, i32* %Other]
- /// %V = load i32* %P2
- /// to:
- /// %V1 = load i32* %Alloca -> will be mem2reg'd
- /// ...
- /// %V2 = load i32* %Other
- /// ...
- /// %V = phi [i32 %V1, i32 %V2]
- ///
- /// We can do this to a select if its only uses are loads and if the operand
- /// to the select can be loaded unconditionally.
- ///
- /// FIXME: This should be hoisted into a generic utility, likely in
- /// Transforms/Util/Local.h
- bool isSafePHIToSpeculate(PHINode &PN, SmallVectorImpl<LoadInst *> &Loads) {
- // For now, we can only do this promotion if the load is in the same block
- // as the PHI, and if there are no stores between the phi and load.
- // TODO: Allow recursive phi users.
- // TODO: Allow stores.
- BasicBlock *BB = PN.getParent();
- unsigned MaxAlign = 0;
- for (Value::use_iterator UI = PN.use_begin(), UE = PN.use_end();
- UI != UE; ++UI) {
- LoadInst *LI = dyn_cast<LoadInst>(*UI);
- if (LI == 0 || !LI->isSimple()) return false;
-
- // For now we only allow loads in the same block as the PHI. This is
- // a common case that happens when instcombine merges two loads through
- // a PHI.
- if (LI->getParent() != BB) return false;
-
- // Ensure that there are no instructions between the PHI and the load that
- // could store.
- for (BasicBlock::iterator BBI = &PN; &*BBI != LI; ++BBI)
- if (BBI->mayWriteToMemory())
- return false;
-
- MaxAlign = std::max(MaxAlign, LI->getAlignment());
- Loads.push_back(LI);
- }
-
- // We can only transform this if it is safe to push the loads into the
- // predecessor blocks. The only thing to watch out for is that we can't put
- // a possibly trapping load in the predecessor if it is a critical edge.
- for (unsigned Idx = 0, Num = PN.getNumIncomingValues(); Idx != Num;
- ++Idx) {
- TerminatorInst *TI = PN.getIncomingBlock(Idx)->getTerminator();
- Value *InVal = PN.getIncomingValue(Idx);
-
- // If the value is produced by the terminator of the predecessor (an
- // invoke) or it has side-effects, there is no valid place to put a load
- // in the predecessor.
- if (TI == InVal || TI->mayHaveSideEffects())
- return false;
-
- // If the predecessor has a single successor, then the edge isn't
- // critical.
- if (TI->getNumSuccessors() == 1)
- continue;
-
- // If this pointer is always safe to load, or if we can prove that there
- // is already a load in the block, then we can move the load to the pred
- // block.
- if (InVal->isDereferenceablePointer() ||
- isSafeToLoadUnconditionally(InVal, TI, MaxAlign, &TD))
- continue;
-
- return false;
- }
-
- return true;
- }
-
bool visitPHINode(PHINode &PN) {
DEBUG(dbgs() << " original: " << PN << "\n");
+
// We would like to compute a new pointer in only one place, but have it be
// as local as possible to the PHI. To do that, we re-use the location of
// the old pointer, which necessarily must be in the right position to
// dominate the PHI.
IRBuilder<> PtrBuilder(cast<Instruction>(OldPtr));
- SmallVector<LoadInst *, 4> Loads;
- if (!isSafePHIToSpeculate(PN, Loads)) {
- Value *NewPtr = getAdjustedAllocaPtr(PtrBuilder, OldPtr->getType());
- // Replace the operands which were using the old pointer.
- User::op_iterator OI = PN.op_begin(), OE = PN.op_end();
- for (; OI != OE; ++OI)
- if (*OI == OldPtr)
- *OI = NewPtr;
-
- DEBUG(dbgs() << " to: " << PN << "\n");
- deleteIfTriviallyDead(OldPtr);
- return false;
- }
- assert(!Loads.empty());
-
- Type *LoadTy = cast<PointerType>(PN.getType())->getElementType();
- IRBuilder<> PHIBuilder(&PN);
- PHINode *NewPN = PHIBuilder.CreatePHI(LoadTy, PN.getNumIncomingValues());
- NewPN->takeName(&PN);
-
- // Get the TBAA tag and alignment to use from one of the loads. It doesn't
- // matter which one we get and if any differ, it doesn't matter.
- LoadInst *SomeLoad = cast<LoadInst>(Loads.back());
- MDNode *TBAATag = SomeLoad->getMetadata(LLVMContext::MD_tbaa);
- unsigned Align = SomeLoad->getAlignment();
Value *NewPtr = getAdjustedAllocaPtr(PtrBuilder, OldPtr->getType());
+ // Replace the operands which were using the old pointer.
+ User::op_iterator OI = PN.op_begin(), OE = PN.op_end();
+ for (; OI != OE; ++OI)
+ if (*OI == OldPtr)
+ *OI = NewPtr;
- // Rewrite all loads of the PN to use the new PHI.
- do {
- LoadInst *LI = Loads.pop_back_val();
- LI->replaceAllUsesWith(NewPN);
- Pass.DeadInsts.push_back(LI);
- } while (!Loads.empty());
-
- // Inject loads into all of the pred blocks.
- for (unsigned Idx = 0, Num = PN.getNumIncomingValues(); Idx != Num; ++Idx) {
- BasicBlock *Pred = PN.getIncomingBlock(Idx);
- TerminatorInst *TI = Pred->getTerminator();
- Value *InVal = PN.getIncomingValue(Idx);
- IRBuilder<> PredBuilder(TI);
-
- // Map the value to the new alloca pointer if this was the old alloca
- // pointer.
- bool ThisOperand = InVal == OldPtr;
- if (ThisOperand)
- InVal = NewPtr;
-
- LoadInst *Load
- = PredBuilder.CreateLoad(InVal, getName(".sroa.speculate." +
- Pred->getName()));
- ++NumLoadsSpeculated;
- Load->setAlignment(Align);
- if (TBAATag)
- Load->setMetadata(LLVMContext::MD_tbaa, TBAATag);
- NewPN->addIncoming(Load, Pred);
-
- if (ThisOperand)
- continue;
- Instruction *OtherPtr = dyn_cast<Instruction>(InVal);
- if (!OtherPtr)
- // No uses to rewrite.
- continue;
-
- // Try to lookup and rewrite any partition uses corresponding to this phi
- // input.
- AllocaPartitioning::iterator PI
- = P.findPartitionForPHIOrSelectOperand(PN, OtherPtr);
- if (PI != P.end()) {
- // If the other pointer is within the partitioning, replace the PHI in
- // its uses with the load we just speculated, or add another load for
- // it to rewrite if we've already replaced the PHI.
- AllocaPartitioning::use_iterator UI
- = P.findPartitionUseForPHIOrSelectOperand(PN, OtherPtr);
- if (isa<PHINode>(*UI->User))
- UI->User = Load;
- else {
- AllocaPartitioning::PartitionUse OtherUse = *UI;
- OtherUse.User = Load;
- P.use_push_back(PI, OtherUse);
- }
- }
- }
- DEBUG(dbgs() << " speculated to: " << *NewPN << "\n");
- return NewPtr == &NewAI;
- }
-
- /// Select instructions that use an alloca and are subsequently loaded can be
- /// rewritten to load both input pointers and then select between the result,
- /// allowing the load of the alloca to be promoted.
- /// From this:
- /// %P2 = select i1 %cond, i32* %Alloca, i32* %Other
- /// %V = load i32* %P2
- /// to:
- /// %V1 = load i32* %Alloca -> will be mem2reg'd
- /// %V2 = load i32* %Other
- /// %V = select i1 %cond, i32 %V1, i32 %V2
- ///
- /// We can do this to a select if its only uses are loads and if the operand
- /// to the select can be loaded unconditionally.
- bool isSafeSelectToSpeculate(SelectInst &SI,
- SmallVectorImpl<LoadInst *> &Loads) {
- Value *TValue = SI.getTrueValue();
- Value *FValue = SI.getFalseValue();
- bool TDerefable = TValue->isDereferenceablePointer();
- bool FDerefable = FValue->isDereferenceablePointer();
-
- for (Value::use_iterator UI = SI.use_begin(), UE = SI.use_end();
- UI != UE; ++UI) {
- LoadInst *LI = dyn_cast<LoadInst>(*UI);
- if (LI == 0 || !LI->isSimple()) return false;
-
- // Both operands to the select need to be dereferencable, either
- // absolutely (e.g. allocas) or at this point because we can see other
- // accesses to it.
- if (!TDerefable && !isSafeToLoadUnconditionally(TValue, LI,
- LI->getAlignment(), &TD))
- return false;
- if (!FDerefable && !isSafeToLoadUnconditionally(FValue, LI,
- LI->getAlignment(), &TD))
- return false;
- Loads.push_back(LI);
- }
-
- return true;
+ DEBUG(dbgs() << " to: " << PN << "\n");
+ deleteIfTriviallyDead(OldPtr);
+ return false;
}
bool visitSelectInst(SelectInst &SI) {
@@ -2564,66 +2772,12 @@ private:
assert(SI.getFalseValue() != OldPtr && "Pointer is both operands!");
else
assert(SI.getFalseValue() == OldPtr && "Pointer isn't an operand!");
- Value *NewPtr = getAdjustedAllocaPtr(IRB, OldPtr->getType());
-
- // If the select isn't safe to speculate, just use simple logic to emit it.
- SmallVector<LoadInst *, 4> Loads;
- if (!isSafeSelectToSpeculate(SI, Loads)) {
- SI.setOperand(IsTrueVal ? 1 : 2, NewPtr);
- DEBUG(dbgs() << " to: " << SI << "\n");
- deleteIfTriviallyDead(OldPtr);
- return false;
- }
-
- Value *OtherPtr = IsTrueVal ? SI.getFalseValue() : SI.getTrueValue();
- AllocaPartitioning::iterator PI
- = P.findPartitionForPHIOrSelectOperand(SI, OtherPtr);
- AllocaPartitioning::PartitionUse OtherUse;
- if (PI != P.end()) {
- // If the other pointer is within the partitioning, remove the select
- // from its uses. We'll add in the new loads below.
- AllocaPartitioning::use_iterator UI
- = P.findPartitionUseForPHIOrSelectOperand(SI, OtherPtr);
- OtherUse = *UI;
- P.use_erase(PI, UI);
- }
-
- Value *TV = IsTrueVal ? NewPtr : SI.getTrueValue();
- Value *FV = IsTrueVal ? SI.getFalseValue() : NewPtr;
- // Replace the loads of the select with a select of two loads.
- while (!Loads.empty()) {
- LoadInst *LI = Loads.pop_back_val();
-
- IRB.SetInsertPoint(LI);
- LoadInst *TL =
- IRB.CreateLoad(TV, getName("." + LI->getName() + ".true"));
- LoadInst *FL =
- IRB.CreateLoad(FV, getName("." + LI->getName() + ".false"));
- NumLoadsSpeculated += 2;
- if (PI != P.end()) {
- LoadInst *OtherLoad = IsTrueVal ? FL : TL;
- assert(OtherUse.Ptr == OtherLoad->getOperand(0));
- OtherUse.User = OtherLoad;
- P.use_push_back(PI, OtherUse);
- }
-
- // Transfer alignment and TBAA info if present.
- TL->setAlignment(LI->getAlignment());
- FL->setAlignment(LI->getAlignment());
- if (MDNode *Tag = LI->getMetadata(LLVMContext::MD_tbaa)) {
- TL->setMetadata(LLVMContext::MD_tbaa, Tag);
- FL->setMetadata(LLVMContext::MD_tbaa, Tag);
- }
-
- Value *V = IRB.CreateSelect(SI.getCondition(), TL, FL);
- V->takeName(LI);
- DEBUG(dbgs() << " speculated to: " << *V << "\n");
- LI->replaceAllUsesWith(V);
- Pass.DeadInsts.push_back(LI);
- }
+ Value *NewPtr = getAdjustedAllocaPtr(IRB, OldPtr->getType());
+ SI.setOperand(IsTrueVal ? 1 : 2, NewPtr);
+ DEBUG(dbgs() << " to: " << SI << "\n");
deleteIfTriviallyDead(OldPtr);
- return NewPtr == &NewAI;
+ return false;
}
};
@@ -2639,7 +2793,7 @@ class AggLoadStoreRewriter : public InstVisitor<AggLoadStoreRewriter, bool> {
// Befriend the base class so it can delegate to private visit methods.
friend class llvm::InstVisitor<AggLoadStoreRewriter, bool>;
- const TargetData &TD;
+ const DataLayout &TD;
/// Queue of pointer uses to analyze and potentially rewrite.
SmallVector<Use *, 8> Queue;
@@ -2652,7 +2806,7 @@ class AggLoadStoreRewriter : public InstVisitor<AggLoadStoreRewriter, bool> {
Use *U;
public:
- AggLoadStoreRewriter(const TargetData &TD) : TD(TD) {}
+ AggLoadStoreRewriter(const DataLayout &TD) : TD(TD) {}
/// Rewrite loads and stores through a pointer and all pointers derived from
/// it.
@@ -2852,7 +3006,7 @@ private:
/// when the size or offset cause either end of type-based partition to be off.
/// Also, this is a best-effort routine. It is reasonable to give up and not
/// return a type if necessary.
-static Type *getTypePartition(const TargetData &TD, Type *Ty,
+static Type *getTypePartition(const DataLayout &TD, Type *Ty,
uint64_t Offset, uint64_t Size) {
if (Offset == 0 && TD.getTypeAllocSize(Ty) == Size)
return Ty;
@@ -2968,9 +3122,23 @@ bool SROA::rewriteAllocaPartition(AllocaInst &AI,
AllocaPartitioning &P,
AllocaPartitioning::iterator PI) {
uint64_t AllocaSize = PI->EndOffset - PI->BeginOffset;
- if (P.use_begin(PI) == P.use_end(PI))
+ bool IsLive = false;
+ for (AllocaPartitioning::use_iterator UI = P.use_begin(PI),
+ UE = P.use_end(PI);
+ UI != UE && !IsLive; ++UI)
+ if (UI->U)
+ IsLive = true;
+ if (!IsLive)
return false; // No live uses left of this partition.
+ DEBUG(dbgs() << "Speculating PHIs and selects in partition "
+ << "[" << PI->BeginOffset << "," << PI->EndOffset << ")\n");
+
+ PHIOrSelectSpeculator Speculator(*TD, P, *this);
+ DEBUG(dbgs() << " speculating ");
+ DEBUG(P.print(dbgs(), PI, ""));
+ Speculator.visitUsers(PI);
+
// Try to compute a friendly type for this partition of the alloca. This
// won't always succeed, in which case we fall back to a legal integer type
// or an i8 array of an appropriate size.
@@ -3024,11 +3192,16 @@ bool SROA::rewriteAllocaPartition(AllocaInst &AI,
<< "[" << PI->BeginOffset << "," << PI->EndOffset << ") to: "
<< *NewAI << "\n");
+ // Track the high watermark of the post-promotion worklist. We will reset it
+ // to this point if the alloca is not in fact scheduled for promotion.
+ unsigned PPWOldSize = PostPromotionWorklist.size();
+
AllocaPartitionRewriter Rewriter(*TD, P, PI, *this, AI, *NewAI,
PI->BeginOffset, PI->EndOffset);
DEBUG(dbgs() << " rewriting ");
DEBUG(P.print(dbgs(), PI, ""));
- if (Rewriter.visitUsers(P.use_begin(PI), P.use_end(PI))) {
+ bool Promotable = Rewriter.visitUsers(P.use_begin(PI), P.use_end(PI));
+ if (Promotable) {
DEBUG(dbgs() << " and queuing for promotion\n");
PromotableAllocas.push_back(NewAI);
} else if (NewAI != &AI) {
@@ -3037,6 +3210,12 @@ bool SROA::rewriteAllocaPartition(AllocaInst &AI,
// alloca which didn't actually change and didn't get promoted.
Worklist.insert(NewAI);
}
+
+ // Drop any post-promotion work items if promotion didn't happen.
+ if (!Promotable)
+ while (PostPromotionWorklist.size() > PPWOldSize)
+ PostPromotionWorklist.pop_back();
+
return true;
}
@@ -3070,13 +3249,6 @@ bool SROA::runOnAlloca(AllocaInst &AI) {
TD->getTypeAllocSize(AI.getAllocatedType()) == 0)
return false;
- // First check if this is a non-aggregate type that we should simply promote.
- if (!AI.getAllocatedType()->isAggregateType() && isAllocaPromotable(&AI)) {
- DEBUG(dbgs() << " Trivially scalar type, queuing for promotion...\n");
- PromotableAllocas.push_back(&AI);
- return false;
- }
-
bool Changed = false;
// First, split any FCA loads and stores touching this alloca to promote
@@ -3090,10 +3262,6 @@ bool SROA::runOnAlloca(AllocaInst &AI) {
if (P.isEscaped())
return Changed;
- // No partitions to split. Leave the dead alloca for a later pass to clean up.
- if (P.begin() == P.end())
- return Changed;
-
// Delete all the dead users of this alloca before splitting and rewriting it.
for (AllocaPartitioning::dead_user_iterator DI = P.dead_user_begin(),
DE = P.dead_user_end();
@@ -3115,6 +3283,10 @@ bool SROA::runOnAlloca(AllocaInst &AI) {
}
}
+ // No partitions to split. Leave the dead alloca for a later pass to clean up.
+ if (P.begin() == P.end())
+ return Changed;
+
return splitAlloca(AI, P) || Changed;
}
@@ -3216,15 +3388,17 @@ namespace {
const SetType &Set;
public:
+ typedef AllocaInst *argument_type;
+
IsAllocaInSet(const SetType &Set) : Set(Set) {}
- bool operator()(AllocaInst *AI) { return Set.count(AI); }
+ bool operator()(AllocaInst *AI) const { return Set.count(AI); }
};
}
bool SROA::runOnFunction(Function &F) {
DEBUG(dbgs() << "SROA function: " << F.getName() << "\n");
C = &F.getContext();
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
if (!TD) {
DEBUG(dbgs() << " Skipping SROA -- no target data!\n");
return false;
@@ -3242,19 +3416,29 @@ bool SROA::runOnFunction(Function &F) {
// the list of promotable allocas.
SmallPtrSet<AllocaInst *, 4> DeletedAllocas;
- while (!Worklist.empty()) {
- Changed |= runOnAlloca(*Worklist.pop_back_val());
- deleteDeadInstructions(DeletedAllocas);
- if (!DeletedAllocas.empty()) {
- PromotableAllocas.erase(std::remove_if(PromotableAllocas.begin(),
- PromotableAllocas.end(),
- IsAllocaInSet(DeletedAllocas)),
- PromotableAllocas.end());
- DeletedAllocas.clear();
+ do {
+ while (!Worklist.empty()) {
+ Changed |= runOnAlloca(*Worklist.pop_back_val());
+ deleteDeadInstructions(DeletedAllocas);
+
+ // Remove the deleted allocas from various lists so that we don't try to
+ // continue processing them.
+ if (!DeletedAllocas.empty()) {
+ Worklist.remove_if(IsAllocaInSet(DeletedAllocas));
+ PostPromotionWorklist.remove_if(IsAllocaInSet(DeletedAllocas));
+ PromotableAllocas.erase(std::remove_if(PromotableAllocas.begin(),
+ PromotableAllocas.end(),
+ IsAllocaInSet(DeletedAllocas)),
+ PromotableAllocas.end());
+ DeletedAllocas.clear();
+ }
}
- }
- Changed |= promoteAllocas(F);
+ Changed |= promoteAllocas(F);
+
+ Worklist = PostPromotionWorklist;
+ PostPromotionWorklist.clear();
+ } while (!Worklist.empty());
return Changed;
}
diff --git a/lib/Transforms/Scalar/Scalar.cpp b/lib/Transforms/Scalar/Scalar.cpp
index 95b6fa7c7f..39630fd027 100644
--- a/lib/Transforms/Scalar/Scalar.cpp
+++ b/lib/Transforms/Scalar/Scalar.cpp
@@ -19,7 +19,7 @@
#include "llvm/PassManager.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/Verifier.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Transforms/Scalar.h"
using namespace llvm;
diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
index 8090fdf178..a46d09c320 100644
--- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp
+++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
@@ -46,7 +46,7 @@
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
#include "llvm/Transforms/Utils/SSAUpdater.h"
@@ -87,7 +87,7 @@ namespace {
private:
bool HasDomTree;
- TargetData *TD;
+ DataLayout *TD;
/// DeadInsts - Keep track of instructions we have made dead, so that
/// we can remove them after we are done working.
@@ -258,7 +258,7 @@ namespace {
class ConvertToScalarInfo {
/// AllocaSize - The size of the alloca being considered in bytes.
unsigned AllocaSize;
- const TargetData &TD;
+ const DataLayout &TD;
unsigned ScalarLoadThreshold;
/// IsNotTrivial - This is set to true if there is some access to the object
@@ -301,7 +301,7 @@ class ConvertToScalarInfo {
bool HadDynamicAccess;
public:
- explicit ConvertToScalarInfo(unsigned Size, const TargetData &td,
+ explicit ConvertToScalarInfo(unsigned Size, const DataLayout &td,
unsigned SLT)
: AllocaSize(Size), TD(td), ScalarLoadThreshold(SLT), IsNotTrivial(false),
ScalarKind(Unknown), VectorTy(0), HadNonMemTransferAccess(false),
@@ -1020,11 +1020,11 @@ ConvertScalar_InsertValue(Value *SV, Value *Old,
bool SROA::runOnFunction(Function &F) {
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
bool Changed = performPromotion(F);
- // FIXME: ScalarRepl currently depends on TargetData more than it
+ // FIXME: ScalarRepl currently depends on DataLayout more than it
// theoretically needs to. It should be refactored in order to support
// target-independent IR. Until this is done, just skip the actual
// scalar-replacement portion of this pass.
@@ -1134,7 +1134,7 @@ public:
///
/// We can do this to a select if its only uses are loads and if the operand to
/// the select can be loaded unconditionally.
-static bool isSafeSelectToSpeculate(SelectInst *SI, const TargetData *TD) {
+static bool isSafeSelectToSpeculate(SelectInst *SI, const DataLayout *TD) {
bool TDerefable = SI->getTrueValue()->isDereferenceablePointer();
bool FDerefable = SI->getFalseValue()->isDereferenceablePointer();
@@ -1172,7 +1172,7 @@ static bool isSafeSelectToSpeculate(SelectInst *SI, const TargetData *TD) {
///
/// We can do this to a select if its only uses are loads and if the operand to
/// the select can be loaded unconditionally.
-static bool isSafePHIToSpeculate(PHINode *PN, const TargetData *TD) {
+static bool isSafePHIToSpeculate(PHINode *PN, const DataLayout *TD) {
// For now, we can only do this promotion if the load is in the same block as
// the PHI, and if there are no stores between the phi and load.
// TODO: Allow recursive phi users.
@@ -1236,7 +1236,7 @@ static bool isSafePHIToSpeculate(PHINode *PN, const TargetData *TD) {
/// direct (non-volatile) loads and stores to it. If the alloca is close but
/// not quite there, this will transform the code to allow promotion. As such,
/// it is a non-pure predicate.
-static bool tryToMakeAllocaBePromotable(AllocaInst *AI, const TargetData *TD) {
+static bool tryToMakeAllocaBePromotable(AllocaInst *AI, const DataLayout *TD) {
SetVector<Instruction*, SmallVector<Instruction*, 4>,
SmallPtrSet<Instruction*, 4> > InstsToRewrite;
@@ -2537,7 +2537,7 @@ void SROA::RewriteLoadUserOfWholeAlloca(LoadInst *LI, AllocaInst *AI,
/// HasPadding - Return true if the specified type has any structure or
/// alignment padding in between the elements that would be split apart
/// by SROA; return false otherwise.
-static bool HasPadding(Type *Ty, const TargetData &TD) {
+static bool HasPadding(Type *Ty, const DataLayout &TD) {
if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
Ty = ATy->getElementType();
return TD.getTypeSizeInBits(Ty) != TD.getTypeAllocSizeInBits(Ty);
diff --git a/lib/Transforms/Scalar/SimplifyCFGPass.cpp b/lib/Transforms/Scalar/SimplifyCFGPass.cpp
index 6d27db1b96..84b820b5ce 100644
--- a/lib/Transforms/Scalar/SimplifyCFGPass.cpp
+++ b/lib/Transforms/Scalar/SimplifyCFGPass.cpp
@@ -31,7 +31,7 @@
#include "llvm/Attributes.h"
#include "llvm/Support/CFG.h"
#include "llvm/Pass.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
@@ -293,7 +293,7 @@ static bool mergeEmptyReturnBlocks(Function &F) {
/// iterativelySimplifyCFG - Call SimplifyCFG on all the blocks in the function,
/// iterating until no more changes are made.
-static bool iterativelySimplifyCFG(Function &F, const TargetData *TD) {
+static bool iterativelySimplifyCFG(Function &F, const DataLayout *TD) {
bool Changed = false;
bool LocalChange = true;
while (LocalChange) {
@@ -316,7 +316,7 @@ static bool iterativelySimplifyCFG(Function &F, const TargetData *TD) {
// simplify the CFG.
//
bool CFGSimplifyPass::runOnFunction(Function &F) {
- const TargetData *TD = getAnalysisIfAvailable<TargetData>();
+ const DataLayout *TD = getAnalysisIfAvailable<DataLayout>();
bool EverChanged = removeUnreachableBlocksFromFn(F);
EverChanged |= mergeEmptyReturnBlocks(F);
EverChanged |= iterativelySimplifyCFG(F, TD);
diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
index 65311fe72d..15625f9a40 100644
--- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp
+++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
@@ -31,7 +31,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Config/config.h" // FIXME: Shouldn't depend on host!
using namespace llvm;
@@ -53,7 +53,7 @@ namespace {
class LibCallOptimization {
protected:
Function *Caller;
- const TargetData *TD;
+ const DataLayout *TD;
const TargetLibraryInfo *TLI;
LLVMContext* Context;
public:
@@ -68,7 +68,7 @@ public:
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)
=0;
- Value *OptimizeCall(CallInst *CI, const TargetData *TD,
+ Value *OptimizeCall(CallInst *CI, const DataLayout *TD,
const TargetLibraryInfo *TLI, IRBuilder<> &B) {
Caller = CI->getParent()->getParent();
this->TD = TD;
@@ -159,7 +159,7 @@ struct StrCatOpt : public LibCallOptimization {
if (Len == 0)
return Dst;
- // These optimizations require TargetData.
+ // These optimizations require DataLayout.
if (!TD) return 0;
return EmitStrLenMemCpy(Src, Dst, Len, B);
@@ -220,7 +220,7 @@ struct StrNCatOpt : public StrCatOpt {
// strncat(x, c, 0) -> x
if (SrcLen == 0 || Len == 0) return Dst;
- // These optimizations require TargetData.
+ // These optimizations require DataLayout.
if (!TD) return 0;
// We don't optimize this case
@@ -251,7 +251,7 @@ struct StrChrOpt : public LibCallOptimization {
// of the input string and turn this into memchr.
ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1));
if (CharC == 0) {
- // These optimizations require TargetData.
+ // These optimizations require DataLayout.
if (!TD) return 0;
uint64_t Len = GetStringLength(SrcStr);
@@ -356,7 +356,7 @@ struct StrCmpOpt : public LibCallOptimization {
uint64_t Len1 = GetStringLength(Str1P);
uint64_t Len2 = GetStringLength(Str2P);
if (Len1 && Len2) {
- // These optimizations require TargetData.
+ // These optimizations require DataLayout.
if (!TD) return 0;
return EmitMemCmp(Str1P, Str2P,
@@ -444,7 +444,7 @@ struct StrCpyOpt : public LibCallOptimization {
if (Dst == Src) // strcpy(x,x) -> x
return Src;
- // These optimizations require TargetData.
+ // These optimizations require DataLayout.
if (!TD) return 0;
// See if we can get the length of the input string.
@@ -481,7 +481,7 @@ struct StpCpyOpt: public LibCallOptimization {
FT->getParamType(0) != B.getInt8PtrTy())
return 0;
- // These optimizations require TargetData.
+ // These optimizations require DataLayout.
if (!TD) return 0;
Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1);
@@ -543,7 +543,7 @@ struct StrNCpyOpt : public LibCallOptimization {
if (Len == 0) return Dst; // strncpy(x, y, 0) -> x
- // These optimizations require TargetData.
+ // These optimizations require DataLayout.
if (!TD) return 0;
// Let strncpy handle the zero padding
@@ -832,7 +832,7 @@ struct MemCmpOpt : public LibCallOptimization {
struct MemCpyOpt : public LibCallOptimization {
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
- // These optimizations require TargetData.
+ // These optimizations require DataLayout.
if (!TD) return 0;
FunctionType *FT = Callee->getFunctionType();
@@ -854,7 +854,7 @@ struct MemCpyOpt : public LibCallOptimization {
struct MemMoveOpt : public LibCallOptimization {
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
- // These optimizations require TargetData.
+ // These optimizations require DataLayout.
if (!TD) return 0;
FunctionType *FT = Callee->getFunctionType();
@@ -876,7 +876,7 @@ struct MemMoveOpt : public LibCallOptimization {
struct MemSetOpt : public LibCallOptimization {
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
- // These optimizations require TargetData.
+ // These optimizations require DataLayout.
if (!TD) return 0;
FunctionType *FT = Callee->getFunctionType();
@@ -1304,7 +1304,7 @@ struct SPrintFOpt : public LibCallOptimization {
if (FormatStr[i] == '%')
return 0; // we found a format specifier, bail out.
- // These optimizations require TargetData.
+ // These optimizations require DataLayout.
if (!TD) return 0;
// sprintf(str, fmt) -> llvm.memcpy(str, fmt, strlen(fmt)+1, 1)
@@ -1334,7 +1334,7 @@ struct SPrintFOpt : public LibCallOptimization {
}
if (FormatStr[1] == 's') {
- // These optimizations require TargetData.
+ // These optimizations require DataLayout.
if (!TD) return 0;
// sprintf(dest, "%s", str) -> llvm.memcpy(dest, str, strlen(str)+1, 1)
@@ -1422,7 +1422,7 @@ struct FWriteOpt : public LibCallOptimization {
struct FPutsOpt : public LibCallOptimization {
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
- // These optimizations require TargetData.
+ // These optimizations require DataLayout.
if (!TD) return 0;
// Require two pointers. Also, we can't optimize if return value is used.
@@ -1459,7 +1459,7 @@ struct FPrintFOpt : public LibCallOptimization {
if (FormatStr[i] == '%') // Could handle %% -> % if we cared.
return 0; // We found a format specifier.
- // These optimizations require TargetData.
+ // These optimizations require DataLayout.
if (!TD) return 0;
Value *NewCI = EmitFWrite(CI->getArgOperand(1),
@@ -1749,7 +1749,7 @@ bool SimplifyLibCalls::runOnFunction(Function &F) {
if (Optimizations.empty())
InitOptimizations();
- const TargetData *TD = getAnalysisIfAvailable<TargetData>();
+ const DataLayout *TD = getAnalysisIfAvailable<DataLayout>();
IRBuilder<> Builder(F.getContext());
diff --git a/lib/Transforms/Utils/AddrModeMatcher.cpp b/lib/Transforms/Utils/AddrModeMatcher.cpp
index 0f9dfddf57..6815e411b4 100644
--- a/lib/Transforms/Utils/AddrModeMatcher.cpp
+++ b/lib/Transforms/Utils/AddrModeMatcher.cpp
@@ -16,7 +16,7 @@
#include "llvm/GlobalValue.h"
#include "llvm/Instruction.h"
#include "llvm/Assembly/Writer.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/PatternMatch.h"
@@ -221,7 +221,7 @@ bool AddressingModeMatcher::MatchOperationAddr(User *AddrInst, unsigned Opcode,
unsigned VariableScale = 0;
int64_t ConstantOffset = 0;
- const TargetData *TD = TLI.getTargetData();
+ const DataLayout *TD = TLI.getDataLayout();
gep_type_iterator GTI = gep_type_begin(AddrInst);
for (unsigned i = 1, e = AddrInst->getNumOperands(); i != e; ++i, ++GTI) {
if (StructType *STy = dyn_cast<StructType>(*GTI)) {
diff --git a/lib/Transforms/Utils/BasicBlockUtils.cpp b/lib/Transforms/Utils/BasicBlockUtils.cpp
index 75a7817563..edeebe1b79 100644
--- a/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -22,7 +22,7 @@
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/ErrorHandling.h"
diff --git a/lib/Transforms/Utils/BuildLibCalls.cpp b/lib/Transforms/Utils/BuildLibCalls.cpp
index e13fd716fa..ad01f0b6fa 100644
--- a/lib/Transforms/Utils/BuildLibCalls.cpp
+++ b/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -22,7 +22,7 @@
#include "llvm/Module.h"
#include "llvm/Type.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
using namespace llvm;
@@ -34,7 +34,7 @@ Value *llvm::CastToCStr(Value *V, IRBuilder<> &B) {
/// EmitStrLen - Emit a call to the strlen function to the builder, for the
/// specified pointer. This always returns an integer value of size intptr_t.
-Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const TargetData *TD,
+Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI) {
if (!TLI->has(LibFunc::strlen))
return 0;
@@ -61,7 +61,7 @@ Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const TargetData *TD,
/// specified pointer. Ptr is required to be some pointer type, MaxLen must
/// be of size_t type, and the return value has 'intptr_t' type.
Value *llvm::EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI) {
+ const DataLayout *TD, const TargetLibraryInfo *TLI) {
if (!TLI->has(LibFunc::strnlen))
return 0;
@@ -88,7 +88,7 @@ Value *llvm::EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B,
/// specified pointer and character. Ptr is required to be some pointer type,
/// and the return value has 'i8*' type.
Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI) {
+ const DataLayout *TD, const TargetLibraryInfo *TLI) {
if (!TLI->has(LibFunc::strchr))
return 0;
@@ -109,7 +109,7 @@ Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B,
/// EmitStrNCmp - Emit a call to the strncmp function to the builder.
Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len,
- IRBuilder<> &B, const TargetData *TD,
+ IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI) {
if (!TLI->has(LibFunc::strncmp))
return 0;
@@ -139,7 +139,7 @@ Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len,
/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
/// specified pointer arguments.
Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI,
+ const DataLayout *TD, const TargetLibraryInfo *TLI,
StringRef Name) {
if (!TLI->has(LibFunc::strcpy))
return 0;
@@ -161,7 +161,7 @@ Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
/// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the
/// specified pointer arguments.
Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len,
- IRBuilder<> &B, const TargetData *TD,
+ IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI, StringRef Name) {
if (!TLI->has(LibFunc::strncpy))
return 0;
@@ -185,7 +185,7 @@ Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len,
/// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src
/// are pointers.
Value *llvm::EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
- IRBuilder<> &B, const TargetData *TD,
+ IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI) {
if (!TLI->has(LibFunc::memcpy_chk))
return 0;
@@ -212,7 +212,7 @@ Value *llvm::EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
Value *llvm::EmitMemChr(Value *Ptr, Value *Val,
- Value *Len, IRBuilder<> &B, const TargetData *TD,
+ Value *Len, IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI) {
if (!TLI->has(LibFunc::memchr))
return 0;
@@ -237,7 +237,7 @@ Value *llvm::EmitMemChr(Value *Ptr, Value *Val,
/// EmitMemCmp - Emit a call to the memcmp function.
Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2,
- Value *Len, IRBuilder<> &B, const TargetData *TD,
+ Value *Len, IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI) {
if (!TLI->has(LibFunc::memcmp))
return 0;
@@ -294,7 +294,7 @@ Value *llvm::EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
/// EmitPutChar - Emit a call to the putchar function. This assumes that Char
/// is an integer.
-Value *llvm::EmitPutChar(Value *Char, IRBuilder<> &B, const TargetData *TD,
+Value *llvm::EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI) {
if (!TLI->has(LibFunc::putchar))
return 0;
@@ -316,7 +316,7 @@ Value *llvm::EmitPutChar(Value *Char, IRBuilder<> &B, const TargetData *TD,
/// EmitPutS - Emit a call to the puts function. This assumes that Str is
/// some pointer.
-Value *llvm::EmitPutS(Value *Str, IRBuilder<> &B, const TargetData *TD,
+Value *llvm::EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI) {
if (!TLI->has(LibFunc::puts))
return 0;
@@ -339,7 +339,7 @@ Value *llvm::EmitPutS(Value *Str, IRBuilder<> &B, const TargetData *TD,
/// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
/// an integer and File is a pointer to FILE.
Value *llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI) {
+ const DataLayout *TD, const TargetLibraryInfo *TLI) {
if (!TLI->has(LibFunc::fputc))
return 0;
@@ -370,7 +370,7 @@ Value *llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
/// EmitFPutS - Emit a call to the puts function. Str is required to be a
/// pointer and File is a pointer to FILE.
Value *llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B,
- const TargetData *TD, const TargetLibraryInfo *TLI) {
+ const DataLayout *TD, const TargetLibraryInfo *TLI) {
if (!TLI->has(LibFunc::fputs))
return 0;
@@ -400,7 +400,7 @@ Value *llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B,
/// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is
/// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
Value *llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File,
- IRBuilder<> &B, const TargetData *TD,
+ IRBuilder<> &B, const DataLayout *TD,
const TargetLibraryInfo *TLI) {
if (!TLI->has(LibFunc::fwrite))
return 0;
@@ -436,9 +436,9 @@ Value *llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File,
SimplifyFortifiedLibCalls::~SimplifyFortifiedLibCalls() { }
-bool SimplifyFortifiedLibCalls::fold(CallInst *CI, const TargetData *TD,
+bool SimplifyFortifiedLibCalls::fold(CallInst *CI, const DataLayout *TD,
const TargetLibraryInfo *TLI) {
- // We really need TargetData for later.
+ // We really need DataLayout for later.
if (!TD) return false;
this->CI = CI;
diff --git a/lib/Transforms/Utils/BypassSlowDivision.cpp b/lib/Transforms/Utils/BypassSlowDivision.cpp
index ac18b7d5a0..bee2f7bcb6 100644
--- a/lib/Transforms/Utils/BypassSlowDivision.cpp
+++ b/lib/Transforms/Utils/BypassSlowDivision.cpp
@@ -221,7 +221,7 @@ static bool reuseOrInsertFastDiv(Function &F,
// be profitably bypassed and carried out with a shorter, faster divide.
bool llvm::bypassSlowDivision(Function &F,
Function::iterator &I,
- const DenseMap<Type*, Type*> &BypassTypeMap) {
+ const DenseMap<unsigned int, unsigned int> &BypassWidths) {
DivCacheTy DivCache;
bool MadeChange = false;
@@ -238,14 +238,23 @@ bool llvm::bypassSlowDivision(Function &F,
if (!UseDivOp && !UseRemOp)
continue;
- // Continue if div/rem type is not bypassed
- DenseMap<Type *, Type *>::const_iterator BT =
- BypassTypeMap.find(J->getType());
- if (BT == BypassTypeMap.end())
+ // Skip division on vector types, only optimize integer instructions
+ if (!J->getType()->isIntegerTy())
continue;
- IntegerType *BypassType = cast<IntegerType>(BT->second);
- MadeChange |= reuseOrInsertFastDiv(F, I, J, BypassType, UseDivOp,
+ // Get bitwidth of div/rem instruction
+ IntegerType *T = cast<IntegerType>(J->getType());
+ int bitwidth = T->getBitWidth();
+
+ // Continue if bitwidth is not bypassed
+ DenseMap<unsigned int, unsigned int>::const_iterator BI = BypassWidths.find(bitwidth);
+ if (BI == BypassWidths.end())
+ continue;
+
+ // Get type for div/rem instruction with bypass bitwidth
+ IntegerType *BT = IntegerType::get(J->getContext(), BI->second);
+
+ MadeChange |= reuseOrInsertFastDiv(F, I, J, BT, UseDivOp,
UseSignedOp, DivCache);
}
diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp
index 99237b8390..e2932501f3 100644
--- a/lib/Transforms/Utils/CloneFunction.cpp
+++ b/lib/Transforms/Utils/CloneFunction.cpp
@@ -202,14 +202,14 @@ namespace {
bool ModuleLevelChanges;
const char *NameSuffix;
ClonedCodeInfo *CodeInfo;
- const TargetData *TD;
+ const DataLayout *TD;
public:
PruningFunctionCloner(Function *newFunc, const Function *oldFunc,
ValueToValueMapTy &valueMap,
bool moduleLevelChanges,
const char *nameSuffix,
ClonedCodeInfo *codeInfo,
- const TargetData *td)
+ const DataLayout *td)
: NewFunc(newFunc), OldFunc(oldFunc),
VMap(valueMap), ModuleLevelChanges(moduleLevelChanges),
NameSuffix(nameSuffix), CodeInfo(codeInfo), TD(td) {
@@ -365,7 +365,7 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
SmallVectorImpl<ReturnInst*> &Returns,
const char *NameSuffix,
ClonedCodeInfo *CodeInfo,
- const TargetData *TD,
+ const DataLayout *TD,
Instruction *TheCall) {
assert(NameSuffix && "NameSuffix cannot be null!");
diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp
index 89e89e7acf..009847f87b 100644
--- a/lib/Transforms/Utils/InlineFunction.cpp
+++ b/lib/Transforms/Utils/InlineFunction.cpp
@@ -27,7 +27,7 @@
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Support/CallSite.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Transforms/Utils/Local.h"
using namespace llvm;
@@ -357,7 +357,7 @@ static Value *HandleByValArgument(Value *Arg, Instruction *TheCall,
Type *VoidPtrTy = Type::getInt8PtrTy(Context);
- // Create the alloca. If we have TargetData, use nice alignment.
+ // Create the alloca. If we have DataLayout, use nice alignment.
unsigned Align = 1;
if (IFI.TD)
Align = IFI.TD->getPrefTypeAlignment(AggTy);
diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp
index 2d89516c43..a954d82c05 100644
--- a/lib/Transforms/Utils/Local.cpp
+++ b/lib/Transforms/Utils/Local.cpp
@@ -39,7 +39,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -397,7 +397,7 @@ bool llvm::RecursivelyDeleteDeadPHINode(PHINode *PN,
///
/// This returns true if it changed the code, note that it can delete
/// instructions in other blocks as well in this block.
-bool llvm::SimplifyInstructionsInBlock(BasicBlock *BB, const TargetData *TD,
+bool llvm::SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD,
const TargetLibraryInfo *TLI) {
bool MadeChange = false;
@@ -445,7 +445,7 @@ bool llvm::SimplifyInstructionsInBlock(BasicBlock *BB, const TargetData *TD,
/// .. and delete the predecessor corresponding to the '1', this will attempt to
/// recursively fold the and to 0.
void llvm::RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred,
- TargetData *TD) {
+ DataLayout *TD) {
// This only adjusts blocks with PHI nodes.
if (!isa<PHINode>(BB->begin()))
return;
@@ -760,7 +760,7 @@ bool llvm::EliminateDuplicatePHINodes(BasicBlock *BB) {
/// their preferred alignment from the beginning.
///
static unsigned enforceKnownAlignment(Value *V, unsigned Align,
- unsigned PrefAlign, const TargetData *TD) {
+ unsigned PrefAlign, const DataLayout *TD) {
V = V->stripPointerCasts();
if (AllocaInst *AI = dyn_cast<AllocaInst>(V)) {
@@ -803,7 +803,7 @@ static unsigned enforceKnownAlignment(Value *V, unsigned Align,
/// and it is more than the alignment of the ultimate object, see if we can
/// increase the alignment of the ultimate object, making this check succeed.
unsigned llvm::getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign,
- const TargetData *TD) {
+ const DataLayout *TD) {
assert(V->getType()->isPointerTy() &&
"getOrEnforceKnownAlignment expects a pointer!");
unsigned BitWidth = TD ? TD->getPointerSizeInBits() : 64;
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
index 065325b7c2..af8d112852 100644
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -39,7 +39,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/NoFolder.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include <algorithm>
#include <set>
@@ -79,7 +79,7 @@ namespace {
};
class SimplifyCFGOpt {
- const TargetData *const TD;
+ const DataLayout *const TD;
Value *isValueEqualityComparison(TerminatorInst *TI);
BasicBlock *GetValueEqualityComparisonCases(TerminatorInst *TI,
@@ -99,7 +99,7 @@ class SimplifyCFGOpt {
bool SimplifyCondBranch(BranchInst *BI, IRBuilder <>&Builder);
public:
- explicit SimplifyCFGOpt(const TargetData *td) : TD(td) {}
+ explicit SimplifyCFGOpt(const DataLayout *td) : TD(td) {}
bool run(BasicBlock *BB);
};
}
@@ -382,7 +382,7 @@ static bool DominatesMergePoint(Value *V, BasicBlock *BB,
/// GetConstantInt - Extract ConstantInt from value, looking through IntToPtr
/// and PointerNullValue. Return NULL if value is not a constant int.
-static ConstantInt *GetConstantInt(Value *V, const TargetData *TD) {
+static ConstantInt *GetConstantInt(Value *V, const DataLayout *TD) {
// Normal constant int.
ConstantInt *CI = dyn_cast<ConstantInt>(V);
if (CI || !TD || !isa<Constant>(V) || !V->getType()->isPointerTy())
@@ -416,7 +416,7 @@ static ConstantInt *GetConstantInt(Value *V, const TargetData *TD) {
/// Values vector.
static Value *
GatherConstantCompares(Value *V, std::vector<ConstantInt*> &Vals, Value *&Extra,
- const TargetData *TD, bool isEQ, unsigned &UsedICmps) {
+ const DataLayout *TD, bool isEQ, unsigned &UsedICmps) {
Instruction *I = dyn_cast<Instruction>(V);
if (I == 0) return 0;
@@ -982,7 +982,7 @@ bool SimplifyCFGOpt::FoldValueComparisonIntoPredecessors(TerminatorInst *TI,
Builder.SetInsertPoint(PTI);
// Convert pointer to int before we switch.
if (CV->getType()->isPointerTy()) {
- assert(TD && "Cannot switch on pointer without TargetData");
+ assert(TD && "Cannot switch on pointer without DataLayout");
CV = Builder.CreatePtrToInt(CV, TD->getIntPtrType(CV->getContext()),
"magicptr");
}
@@ -1173,10 +1173,14 @@ static bool SinkThenElseCodeToEnd(BranchInst *BI1) {
// Check that BBEnd has two predecessors and the other predecessor ends with
// an unconditional branch.
- SmallVector<BasicBlock*, 16> Preds(pred_begin(BBEnd), pred_end(BBEnd));
- if (Preds.size() != 2)
+ pred_iterator PI = pred_begin(BBEnd), PE = pred_end(BBEnd);
+ BasicBlock *Pred0 = *PI++;
+ if (PI == PE) // Only one predecessor.
return false;
- BasicBlock *BB2 = (Preds[0] == BB1) ? Preds[1] : Preds[0];
+ BasicBlock *Pred1 = *PI++;
+ if (PI != PE) // More than two predecessors.
+ return false;
+ BasicBlock *BB2 = (Pred0 == BB1) ? Pred1 : Pred0;
BranchInst *BI2 = dyn_cast<BranchInst>(BB2->getTerminator());
if (!BI2 || !BI2->isUnconditional())
return false;
@@ -1506,7 +1510,7 @@ static bool BlockIsSimpleEnoughToThreadThrough(BasicBlock *BB) {
/// that is defined in the same block as the branch and if any PHI entries are
/// constants, thread edges corresponding to that entry to be branches to their
/// ultimate destination.
-static bool FoldCondBranchOnPHI(BranchInst *BI, const TargetData *TD) {
+static bool FoldCondBranchOnPHI(BranchInst *BI, const DataLayout *TD) {
BasicBlock *BB = BI->getParent();
PHINode *PN = dyn_cast<PHINode>(BI->getCondition());
// NOTE: we currently cannot transform this case if the PHI node is used
@@ -1602,7 +1606,7 @@ static bool FoldCondBranchOnPHI(BranchInst *BI, const TargetData *TD) {
/// FoldTwoEntryPHINode - Given a BB that starts with the specified two-entry
/// PHI node, see if we can eliminate it.
-static bool FoldTwoEntryPHINode(PHINode *PN, const TargetData *TD) {
+static bool FoldTwoEntryPHINode(PHINode *PN, const DataLayout *TD) {
// Ok, this is a two entry PHI node. Check to see if this is a simple "if
// statement", which has a very simple dominance structure. Basically, we
// are trying to find the condition that is being branched on, which
@@ -2518,7 +2522,7 @@ static bool SimplifyIndirectBrOnSelect(IndirectBrInst *IBI, SelectInst *SI) {
/// We prefer to split the edge to 'end' so that there is a true/false entry to
/// the PHI, merging the third icmp into the switch.
static bool TryToSimplifyUncondBranchWithICmpInIt(ICmpInst *ICI,
- const TargetData *TD,
+ const DataLayout *TD,
IRBuilder<> &Builder) {
BasicBlock *BB = ICI->getParent();
@@ -2624,7 +2628,7 @@ static bool TryToSimplifyUncondBranchWithICmpInIt(ICmpInst *ICI,
/// SimplifyBranchOnICmpChain - The specified branch is a conditional branch.
/// Check to see if it is branching on an or/and chain of icmp instructions, and
/// fold it into a switch instruction if so.
-static bool SimplifyBranchOnICmpChain(BranchInst *BI, const TargetData *TD,
+static bool SimplifyBranchOnICmpChain(BranchInst *BI, const DataLayout *TD,
IRBuilder<> &Builder) {
Instruction *Cond = dyn_cast<Instruction>(BI->getCondition());
if (Cond == 0) return false;
@@ -2705,7 +2709,7 @@ static bool SimplifyBranchOnICmpChain(BranchInst *BI, const TargetData *TD,
Builder.SetInsertPoint(BI);
// Convert pointer to int before we switch.
if (CompVal->getType()->isPointerTy()) {
- assert(TD && "Cannot switch on pointer without TargetData");
+ assert(TD && "Cannot switch on pointer without DataLayout");
CompVal = Builder.CreatePtrToInt(CompVal,
TD->getIntPtrType(CompVal->getContext()),
"magicptr");
@@ -3254,7 +3258,7 @@ namespace {
ConstantInt *Offset,
const SmallVector<std::pair<ConstantInt*, Constant*>, 4>& Values,
Constant *DefaultValue,
- const TargetData *TD);
+ const DataLayout *TD);
/// BuildLookup - Build instructions with Builder to retrieve the value at
/// the position given by Index in the lookup table.
@@ -3262,7 +3266,7 @@ namespace {
/// WouldFitInRegister - Return true if a table with TableSize elements of
/// type ElementType would fit in a target-legal register.
- static bool WouldFitInRegister(const TargetData *TD,
+ static bool WouldFitInRegister(const DataLayout *TD,
uint64_t TableSize,
const Type *ElementType);
@@ -3301,7 +3305,7 @@ SwitchLookupTable::SwitchLookupTable(Module &M,
ConstantInt *Offset,
const SmallVector<std::pair<ConstantInt*, Constant*>, 4>& Values,
Constant *DefaultValue,
- const TargetData *TD) {
+ const DataLayout *TD) {
assert(Values.size() && "Can't build lookup table without values!");
assert(TableSize >= Values.size() && "Can't fit values in table!");
@@ -3347,8 +3351,11 @@ SwitchLookupTable::SwitchLookupTable(Module &M,
APInt TableInt(TableSize * IT->getBitWidth(), 0);
for (uint64_t I = TableSize; I > 0; --I) {
TableInt <<= IT->getBitWidth();
- ConstantInt *Val = cast<ConstantInt>(TableContents[I - 1]);
- TableInt |= Val->getValue().zext(TableInt.getBitWidth());
+ // Insert values into the bitmap. Undef values are set to zero.
+ if (!isa<UndefValue>(TableContents[I - 1])) {
+ ConstantInt *Val = cast<ConstantInt>(TableContents[I - 1]);
+ TableInt |= Val->getValue().zext(TableInt.getBitWidth());
+ }
}
BitMap = ConstantInt::get(M.getContext(), TableInt);
BitMapElementTy = IT;
@@ -3404,7 +3411,7 @@ Value *SwitchLookupTable::BuildLookup(Value *Index, IRBuilder<> &Builder) {
llvm_unreachable("Unknown lookup table kind!");
}
-bool SwitchLookupTable::WouldFitInRegister(const TargetData *TD,
+bool SwitchLookupTable::WouldFitInRegister(const DataLayout *TD,
uint64_t TableSize,
const Type *ElementType) {
if (!TD)
@@ -3426,7 +3433,7 @@ bool SwitchLookupTable::WouldFitInRegister(const TargetData *TD,
/// types of the results.
static bool ShouldBuildLookupTable(SwitchInst *SI,
uint64_t TableSize,
- const TargetData *TD,
+ const DataLayout *TD,
const SmallDenseMap<PHINode*, Type*>& ResultTypes) {
// The table density should be at least 40%. This is the same criterion as for
// jump tables, see SelectionDAGBuilder::handleJTSwitchCase.
@@ -3450,7 +3457,7 @@ static bool ShouldBuildLookupTable(SwitchInst *SI,
/// replace the switch with lookup tables.
static bool SwitchToLookupTable(SwitchInst *SI,
IRBuilder<> &Builder,
- const TargetData* TD) {
+ const DataLayout* TD) {
assert(SI->getNumCases() > 1 && "Degenerate switch?");
// FIXME: Handle unreachable cases.
@@ -3779,11 +3786,12 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I) {
if (!C)
return false;
- if (!I->hasOneUse()) // Only look at single-use instructions, for compile time
+ if (I->use_empty())
return false;
if (C->isNullValue()) {
- Instruction *Use = I->use_back();
+ // Only look at the first use, avoid hurting compile time with long uselists
+ User *Use = *I->use_begin();
// Now make sure that there are no instructions in between that can alter
// control flow (eg. calls)
@@ -3908,6 +3916,6 @@ bool SimplifyCFGOpt::run(BasicBlock *BB) {
/// eliminates unreachable basic blocks, and does other "peephole" optimization
/// of the CFG. It returns true if a modification was made.
///
-bool llvm::SimplifyCFG(BasicBlock *BB, const TargetData *TD) {
+bool llvm::SimplifyCFG(BasicBlock *BB, const DataLayout *TD) {
return SimplifyCFGOpt(TD).run(BB);
}
diff --git a/lib/Transforms/Utils/SimplifyIndVar.cpp b/lib/Transforms/Utils/SimplifyIndVar.cpp
index 5d673f1824..110f380857 100644
--- a/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ b/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -24,7 +24,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/SimplifyIndVar.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
@@ -44,7 +44,7 @@ namespace {
Loop *L;
LoopInfo *LI;
ScalarEvolution *SE;
- const TargetData *TD; // May be NULL
+ const DataLayout *TD; // May be NULL
SmallVectorImpl<WeakVH> &DeadInsts;
@@ -56,7 +56,7 @@ namespace {
L(Loop),
LI(LPM->getAnalysisIfAvailable<LoopInfo>()),
SE(SE),
- TD(LPM->getAnalysisIfAvailable<TargetData>()),
+ TD(LPM->getAnalysisIfAvailable<DataLayout>()),
DeadInsts(Dead),
Changed(false) {
assert(LI && "IV simplification requires LoopInfo");
diff --git a/lib/Transforms/Utils/SimplifyInstructions.cpp b/lib/Transforms/Utils/SimplifyInstructions.cpp
index 528e6a1e42..65353dc460 100644
--- a/lib/Transforms/Utils/SimplifyInstructions.cpp
+++ b/lib/Transforms/Utils/SimplifyInstructions.cpp
@@ -23,7 +23,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/InstructionSimplify.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h"
@@ -46,7 +46,7 @@ namespace {
/// runOnFunction - Remove instructions that simplify.
bool runOnFunction(Function &F) {
const DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>();
- const TargetData *TD = getAnalysisIfAvailable<TargetData>();
+ const DataLayout *TD = getAnalysisIfAvailable<DataLayout>();
const TargetLibraryInfo *TLI = &getAnalysis<TargetLibraryInfo>();
SmallPtrSet<const Instruction*, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;
bool Changed = false;
diff --git a/lib/Transforms/Vectorize/BBVectorize.cpp b/lib/Transforms/Vectorize/BBVectorize.cpp
index c09dcd2ea9..1296ef11b9 100644
--- a/lib/Transforms/Vectorize/BBVectorize.cpp
+++ b/lib/Transforms/Vectorize/BBVectorize.cpp
@@ -41,7 +41,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/ValueHandle.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Vectorize.h"
#include <algorithm>
@@ -178,7 +178,7 @@ namespace {
: BasicBlockPass(ID), Config(C) {
AA = &P->getAnalysis<AliasAnalysis>();
SE = &P->getAnalysis<ScalarEvolution>();
- TD = P->getAnalysisIfAvailable<TargetData>();
+ TD = P->getAnalysisIfAvailable<DataLayout>();
}
typedef std::pair<Value *, Value *> ValuePair;
@@ -192,7 +192,7 @@ namespace {
AliasAnalysis *AA;
ScalarEvolution *SE;
- TargetData *TD;
+ DataLayout *TD;
// FIXME: const correct?
@@ -364,7 +364,7 @@ namespace {
virtual bool runOnBasicBlock(BasicBlock &BB) {
AA = &getAnalysis<AliasAnalysis>();
SE = &getAnalysis<ScalarEvolution>();
- TD = getAnalysisIfAvailable<TargetData>();
+ TD = getAnalysisIfAvailable<DataLayout>();
return vectorizeBB(BB);
}
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index 19fe156b53..5e23e6fc78 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -1243,7 +1243,7 @@ void AssemblyWriter::writeParamOperand(const Value *Operand,
// Print the type
TypePrinter.print(Operand->getType(), Out);
// Print parameter attributes list
- if (Attrs != Attribute::None)
+ if (Attrs.hasAttributes())
Out << ' ' << Attrs.getAsString();
Out << ' ';
// Print the operand
@@ -1556,7 +1556,7 @@ void AssemblyWriter::printFunction(const Function *F) {
FunctionType *FT = F->getFunctionType();
const AttrListPtr &Attrs = F->getAttributes();
Attributes RetAttrs = Attrs.getRetAttributes();
- if (RetAttrs != Attribute::None)
+ if (RetAttrs.hasAttributes())
Out << Attrs.getRetAttributes().getAsString() << ' ';
TypePrinter.print(F->getReturnType(), Out);
Out << ' ';
@@ -1586,7 +1586,7 @@ void AssemblyWriter::printFunction(const Function *F) {
TypePrinter.print(FT->getParamType(i), Out);
Attributes ArgAttrs = Attrs.getParamAttributes(i+1);
- if (ArgAttrs != Attribute::None)
+ if (ArgAttrs.hasAttributes())
Out << ' ' << ArgAttrs.getAsString();
}
}
@@ -1600,7 +1600,7 @@ void AssemblyWriter::printFunction(const Function *F) {
if (F->hasUnnamedAddr())
Out << " unnamed_addr";
Attributes FnAttrs = Attrs.getFnAttributes();
- if (FnAttrs != Attribute::None)
+ if (FnAttrs.hasAttributes())
Out << ' ' << Attrs.getFnAttributes().getAsString();
if (F->hasSection()) {
Out << " section \"";
@@ -1634,7 +1634,7 @@ void AssemblyWriter::printArgument(const Argument *Arg,
TypePrinter.print(Arg->getType(), Out);
// Output parameter attributes list
- if (Attrs != Attribute::None)
+ if (Attrs.hasAttributes())
Out << ' ' << Attrs.getAsString();
// Output name, if available...
@@ -1849,7 +1849,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
Type *RetTy = FTy->getReturnType();
const AttrListPtr &PAL = CI->getAttributes();
- if (PAL.getRetAttributes() != Attribute::None)
+ if (PAL.getRetAttributes().hasAttributes())
Out << ' ' << PAL.getRetAttributes().getAsString();
// If possible, print out the short form of the call instruction. We can
@@ -1873,7 +1873,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
writeParamOperand(CI->getArgOperand(op), PAL.getParamAttributes(op + 1));
}
Out << ')';
- if (PAL.getFnAttributes() != Attribute::None)
+ if (PAL.getFnAttributes().hasAttributes())
Out << ' ' << PAL.getFnAttributes().getAsString();
} else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
Operand = II->getCalledValue();
@@ -1888,7 +1888,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
PrintCallingConv(II->getCallingConv(), Out);
}
- if (PAL.getRetAttributes() != Attribute::None)
+ if (PAL.getRetAttributes().hasAttributes())
Out << ' ' << PAL.getRetAttributes().getAsString();
// If possible, print out the short form of the invoke instruction. We can
@@ -1913,7 +1913,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
}
Out << ')';
- if (PAL.getFnAttributes() != Attribute::None)
+ if (PAL.getFnAttributes().hasAttributes())
Out << ' ' << PAL.getFnAttributes().getAsString();
Out << "\n to ";
diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp
index 7d3197cb0d..88f20e94a5 100644
--- a/lib/VMCore/Attributes.cpp
+++ b/lib/VMCore/Attributes.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/Attributes.h"
-#include "AttributesImpl.h"
#include "LLVMContextImpl.h"
#include "llvm/Type.h"
#include "llvm/ADT/StringExtras.h"
@@ -25,67 +24,176 @@
using namespace llvm;
//===----------------------------------------------------------------------===//
-// Attribute Function Definitions
+// Attributes Implementation
//===----------------------------------------------------------------------===//
+Attributes::Attributes(uint64_t Val) : Attrs(Val) {}
+
+Attributes::Attributes(Attribute::AttrConst Val) : Attrs(Val.v) {}
+
+Attributes::Attributes(AttributesImpl *A) : Attrs(A->Bits) {}
+
+Attributes::Attributes(const Attributes &A) : Attrs(A.Attrs) {}
+
+// FIXME: This is temporary until we have implemented the uniquified version of
+// AttributesImpl.
+Attributes Attributes::get(Attributes::Builder &B) {
+ return Attributes(B.Bits);
+}
+
+Attributes Attributes::get(LLVMContext &Context, Attributes::Builder &B) {
+ // If there are no attributes, return an empty Attributes class.
+ if (B.Bits == 0)
+ return Attributes();
+
+ // Otherwise, build a key to look up the existing attributes.
+ LLVMContextImpl *pImpl = Context.pImpl;
+ FoldingSetNodeID ID;
+ ID.AddInteger(B.Bits);
+
+ void *InsertPoint;
+ AttributesImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
+
+ if (!PA) {
+ // If we didn't find any existing attributes of the same shape then create a
+ // new one and insert it.
+ PA = new AttributesImpl(B.Bits);
+ pImpl->AttrsSet.InsertNode(PA, InsertPoint);
+ }
+
+ // Return the AttributesList that we found or created.
+ return Attributes(PA);
+}
+
+bool Attributes::hasAttribute(AttrVal Val) const {
+ return Attrs.hasAttribute(Val);
+}
+
+bool Attributes::hasAttributes(const Attributes &A) const {
+ return Attrs.hasAttributes(A);
+}
+
+/// This returns the alignment field of an attribute as a byte alignment value.
+unsigned Attributes::getAlignment() const {
+ if (!hasAttribute(Attributes::Alignment))
+ return 0;
+ return 1U << ((Attrs.getAlignment() >> 16) - 1);
+}
+
+/// This returns the stack alignment field of an attribute as a byte alignment
+/// value.
+unsigned Attributes::getStackAlignment() const {
+ if (!hasAttribute(Attributes::StackAlignment))
+ return 0;
+ return 1U << ((Attrs.getStackAlignment() >> 26) - 1);
+}
+
+bool Attributes::isEmptyOrSingleton() const {
+ return Attrs.isEmptyOrSingleton();
+}
+
+Attributes Attributes::operator | (const Attributes &A) const {
+ return Attributes(Raw() | A.Raw());
+}
+Attributes Attributes::operator & (const Attributes &A) const {
+ return Attributes(Raw() & A.Raw());
+}
+Attributes Attributes::operator ^ (const Attributes &A) const {
+ return Attributes(Raw() ^ A.Raw());
+}
+Attributes &Attributes::operator |= (const Attributes &A) {
+ Attrs.Bits |= A.Raw();
+ return *this;
+}
+Attributes &Attributes::operator &= (const Attributes &A) {
+ Attrs.Bits &= A.Raw();
+ return *this;
+}
+Attributes Attributes::operator ~ () const {
+ return Attributes(~Raw());
+}
+
+uint64_t Attributes::Raw() const {
+ return Attrs.Bits;
+}
+
+Attributes Attributes::typeIncompatible(Type *Ty) {
+ Attributes::Builder Incompatible;
+
+ if (!Ty->isIntegerTy())
+ // Attributes that only apply to integers.
+ Incompatible.addAttribute(Attributes::SExt)
+ .addAttribute(Attributes::ZExt);
+
+ if (!Ty->isPointerTy())
+ // Attributes that only apply to pointers.
+ Incompatible.addAttribute(Attributes::ByVal)
+ .addAttribute(Attributes::Nest)
+ .addAttribute(Attributes::NoAlias)
+ .addAttribute(Attributes::NoCapture)
+ .addAttribute(Attributes::StructRet);
+
+ return Attributes(Incompatible.Bits); // FIXME: Use Attributes::get().
+}
+
std::string Attributes::getAsString() const {
std::string Result;
- if (hasZExtAttr())
+ if (hasAttribute(Attributes::ZExt))
Result += "zeroext ";
- if (hasSExtAttr())
+ if (hasAttribute(Attributes::SExt))
Result += "signext ";
- if (hasNoReturnAttr())
+ if (hasAttribute(Attributes::NoReturn))
Result += "noreturn ";
- if (hasNoUnwindAttr())
+ if (hasAttribute(Attributes::NoUnwind))
Result += "nounwind ";
- if (hasUWTableAttr())
+ if (hasAttribute(Attributes::UWTable))
Result += "uwtable ";
- if (hasReturnsTwiceAttr())
+ if (hasAttribute(Attributes::ReturnsTwice))
Result += "returns_twice ";
- if (hasInRegAttr())
+ if (hasAttribute(Attributes::InReg))
Result += "inreg ";
- if (hasNoAliasAttr())
+ if (hasAttribute(Attributes::NoAlias))
Result += "noalias ";
- if (hasNoCaptureAttr())
+ if (hasAttribute(Attributes::NoCapture))
Result += "nocapture ";
- if (hasStructRetAttr())
+ if (hasAttribute(Attributes::StructRet))
Result += "sret ";
- if (hasByValAttr())
+ if (hasAttribute(Attributes::ByVal))
Result += "byval ";
- if (hasNestAttr())
+ if (hasAttribute(Attributes::Nest))
Result += "nest ";
- if (hasReadNoneAttr())
+ if (hasAttribute(Attributes::ReadNone))
Result += "readnone ";
- if (hasReadOnlyAttr())
+ if (hasAttribute(Attributes::ReadOnly))
Result += "readonly ";
- if (hasOptimizeForSizeAttr())
+ if (hasAttribute(Attributes::OptimizeForSize))
Result += "optsize ";
- if (hasNoInlineAttr())
+ if (hasAttribute(Attributes::NoInline))
Result += "noinline ";
- if (hasInlineHintAttr())
+ if (hasAttribute(Attributes::InlineHint))
Result += "inlinehint ";
- if (hasAlwaysInlineAttr())
+ if (hasAttribute(Attributes::AlwaysInline))
Result += "alwaysinline ";
- if (hasStackProtectAttr())
+ if (hasAttribute(Attributes::StackProtect))
Result += "ssp ";
- if (hasStackProtectReqAttr())
+ if (hasAttribute(Attributes::StackProtectReq))
Result += "sspreq ";
- if (hasNoRedZoneAttr())
+ if (hasAttribute(Attributes::NoRedZone))
Result += "noredzone ";
- if (hasNoImplicitFloatAttr())
+ if (hasAttribute(Attributes::NoImplicitFloat))
Result += "noimplicitfloat ";
- if (hasNakedAttr())
+ if (hasAttribute(Attributes::Naked))
Result += "naked ";
- if (hasNonLazyBindAttr())
+ if (hasAttribute(Attributes::NonLazyBind))
Result += "nonlazybind ";
- if (hasAddressSafetyAttr())
+ if (hasAttribute(Attributes::AddressSafety))
Result += "address_safety ";
- if (hasStackAlignmentAttr()) {
+ if (hasAttribute(Attributes::StackAlignment)) {
Result += "alignstack(";
Result += utostr(getStackAlignment());
Result += ") ";
}
- if (hasAlignmentAttr()) {
+ if (hasAttribute(Attributes::Alignment)) {
Result += "align ";
Result += utostr(getAlignment());
Result += " ";
@@ -96,49 +204,117 @@ std::string Attributes::getAsString() const {
return Result;
}
-Attributes Attributes::typeIncompatible(Type *Ty) {
- Attributes Incompatible = Attribute::None;
-
- if (!Ty->isIntegerTy())
- // Attributes that only apply to integers.
- Incompatible |= Attribute::SExt | Attribute::ZExt;
-
- if (!Ty->isPointerTy())
- // Attributes that only apply to pointers.
- Incompatible |= Attribute::ByVal | Attribute::Nest | Attribute::NoAlias |
- Attribute::StructRet | Attribute::NoCapture;
-
- return Incompatible;
+//===----------------------------------------------------------------------===//
+// Attributes::Builder Implementation
+//===----------------------------------------------------------------------===//
+
+Attributes::Builder &Attributes::Builder::
+addAttribute(Attributes::AttrVal Val) {
+ Bits |= AttributesImpl::getAttrMask(Val);
+ return *this;
+}
+
+void Attributes::Builder::addAlignmentAttr(unsigned Align) {
+ if (Align == 0) return;
+ assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
+ assert(Align <= 0x40000000 && "Alignment too large.");
+ Bits |= (Log2_32(Align) + 1) << 16;
+}
+void Attributes::Builder::addStackAlignmentAttr(unsigned Align) {
+ // Default alignment, allow the target to define how to align it.
+ if (Align == 0) return;
+ assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
+ assert(Align <= 0x100 && "Alignment too large.");
+ Bits |= (Log2_32(Align) + 1) << 26;
+}
+
+Attributes::Builder &Attributes::Builder::
+removeAttribute(Attributes::AttrVal Val) {
+ Bits &= ~AttributesImpl::getAttrMask(Val);
+ return *this;
+}
+
+void Attributes::Builder::removeAttributes(const Attributes &A) {
+ Bits &= ~A.Raw();
+}
+
+bool Attributes::Builder::hasAttributes() const {
+ return Bits != 0;
+}
+bool Attributes::Builder::hasAttributes(const Attributes &A) const {
+ return Bits & A.Raw();
+}
+bool Attributes::Builder::hasAlignmentAttr() const {
+ return Bits & AttributesImpl::getAttrMask(Attributes::Alignment);
+}
+
+uint64_t Attributes::Builder::getAlignment() const {
+ if (!hasAlignmentAttr())
+ return 0;
+ return 1U <<
+ (((Bits & AttributesImpl::getAttrMask(Attributes::Alignment)) >> 16) - 1);
}
//===----------------------------------------------------------------------===//
// AttributeImpl Definition
//===----------------------------------------------------------------------===//
-Attributes::Attributes(AttributesImpl *A) : Bits(0) {}
+uint64_t AttributesImpl::getAttrMask(uint64_t Val) {
+ switch (Val) {
+ case Attributes::None: return 0;
+ case Attributes::ZExt: return 1 << 0;
+ case Attributes::SExt: return 1 << 1;
+ case Attributes::NoReturn: return 1 << 2;
+ case Attributes::InReg: return 1 << 3;
+ case Attributes::StructRet: return 1 << 4;
+ case Attributes::NoUnwind: return 1 << 5;
+ case Attributes::NoAlias: return 1 << 6;
+ case Attributes::ByVal: return 1 << 7;
+ case Attributes::Nest: return 1 << 8;
+ case Attributes::ReadNone: return 1 << 9;
+ case Attributes::ReadOnly: return 1 << 10;
+ case Attributes::NoInline: return 1 << 11;
+ case Attributes::AlwaysInline: return 1 << 12;
+ case Attributes::OptimizeForSize: return 1 << 13;
+ case Attributes::StackProtect: return 1 << 14;
+ case Attributes::StackProtectReq: return 1 << 15;
+ case Attributes::Alignment: return 31 << 16;
+ case Attributes::NoCapture: return 1 << 21;
+ case Attributes::NoRedZone: return 1 << 22;
+ case Attributes::NoImplicitFloat: return 1 << 23;
+ case Attributes::Naked: return 1 << 24;
+ case Attributes::InlineHint: return 1 << 25;
+ case Attributes::StackAlignment: return 7 << 26;
+ case Attributes::ReturnsTwice: return 1 << 29;
+ case Attributes::UWTable: return 1 << 30;
+ case Attributes::NonLazyBind: return 1U << 31;
+ case Attributes::AddressSafety: return 1ULL << 32;
+ }
+ llvm_unreachable("Unsupported attribute type");
+}
+
+bool AttributesImpl::hasAttribute(uint64_t A) const {
+ return (Bits & getAttrMask(A)) != 0;
+}
-Attributes Attributes::get(LLVMContext &Context, Attributes::Builder &B) {
- // If there are no attributes, return an empty Attributes class.
- if (B.Bits == 0)
- return Attributes();
+bool AttributesImpl::hasAttributes() const {
+ return Bits != 0;
+}
- // Otherwise, build a key to look up the existing attributes.
- LLVMContextImpl *pImpl = Context.pImpl;
- FoldingSetNodeID ID;
- ID.AddInteger(B.Bits);
+bool AttributesImpl::hasAttributes(const Attributes &A) const {
+ return Bits & A.Raw(); // FIXME: Raw() won't work here in the future.
+}
- void *InsertPoint;
- AttributesImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
+uint64_t AttributesImpl::getAlignment() const {
+ return Bits & getAttrMask(Attributes::Alignment);
+}
- if (!PA) {
- // If we didn't find any existing attributes of the same shape then create a
- // new one and insert it.
- PA = new AttributesImpl(B.Bits);
- pImpl->AttrsSet.InsertNode(PA, InsertPoint);
- }
+uint64_t AttributesImpl::getStackAlignment() const {
+ return Bits & getAttrMask(Attributes::StackAlignment);
+}
- // Return the AttributesList that we found or created.
- return Attributes(PA);
+bool AttributesImpl::isEmptyOrSingleton() const {
+ return (Bits & (Bits - 1)) == 0;
}
//===----------------------------------------------------------------------===//
@@ -302,6 +478,15 @@ bool AttrListPtr::hasAttrSomewhere(Attributes Attr) const {
return false;
}
+unsigned AttrListPtr::getNumAttrs() const {
+ return AttrList ? AttrList->Attrs.size() : 0;
+}
+
+Attributes &AttrListPtr::getAttributesAtIndex(unsigned i) const {
+ assert(AttrList && "Trying to get an attribute from an empty list!");
+ assert(i < AttrList->Attrs.size() && "Index out of range!");
+ return AttrList->Attrs[i].Attrs;
+}
AttrListPtr AttrListPtr::addAttr(unsigned Idx, Attributes Attrs) const {
Attributes OldAttrs = getAttributes(Idx);
@@ -348,7 +533,8 @@ AttrListPtr AttrListPtr::removeAttr(unsigned Idx, Attributes Attrs) const {
#ifndef NDEBUG
// FIXME it is not obvious how this should work for alignment.
// For now, say we can't pass in alignment, which no current use does.
- assert(!Attrs.hasAlignmentAttr() && "Attempt to exclude alignment!");
+ assert(!Attrs.hasAttribute(Attributes::Alignment) &&
+ "Attempt to exclude alignment!");
#endif
if (AttrList == 0) return AttrListPtr();
diff --git a/lib/VMCore/CMakeLists.txt b/lib/VMCore/CMakeLists.txt
index c17e79454e..6c30967974 100644
--- a/lib/VMCore/CMakeLists.txt
+++ b/lib/VMCore/CMakeLists.txt
@@ -8,6 +8,7 @@ add_llvm_library(LLVMCore
ConstantFold.cpp
Constants.cpp
Core.cpp
+ DataLayout.cpp
DebugInfo.cpp
DebugLoc.cpp
DIBuilder.cpp
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index 8e82876243..cc386a8d86 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -12,7 +12,7 @@
// ConstantExpr::get* methods to automatically fold constants when possible.
//
// The current constant folding implementation is implemented in two pieces: the
-// pieces that don't need TargetData, and the pieces that do. This is to avoid
+// pieces that don't need DataLayout, and the pieces that do. This is to avoid
// a dependence in VMCore on Target.
//
//===----------------------------------------------------------------------===//
diff --git a/lib/VMCore/DIBuilder.cpp b/lib/VMCore/DIBuilder.cpp
index 6a29a02399..c331304df1 100644
--- a/lib/VMCore/DIBuilder.cpp
+++ b/lib/VMCore/DIBuilder.cpp
@@ -550,7 +550,7 @@ DIType DIBuilder::createEnumerationType(DIDescriptor Scope, StringRef Name,
uint64_t SizeInBits,
uint64_t AlignInBits,
DIArray Elements,
- DIType ClassType, unsigned Flags) {
+ DIType ClassType) {
// TAG_enumeration_type is encoded in DICompositeType format.
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_enumeration_type),
@@ -561,7 +561,7 @@ DIType DIBuilder::createEnumerationType(DIDescriptor Scope, StringRef Name,
ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
ConstantInt::get(Type::getInt32Ty(VMContext), 0),
- ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
+ ConstantInt::get(Type::getInt32Ty(VMContext), 0),
ClassType,
Elements,
ConstantInt::get(Type::getInt32Ty(VMContext), 0),
@@ -706,7 +706,9 @@ DIType DIBuilder::createTemporaryType(DIFile F) {
/// can be RAUW'd if the full type is seen.
DIType DIBuilder::createForwardDecl(unsigned Tag, StringRef Name,
DIDescriptor Scope, DIFile F,
- unsigned Line, unsigned RuntimeLang) {
+ unsigned Line, unsigned RuntimeLang,
+ uint64_t SizeInBits,
+ uint64_t AlignInBits) {
// Create a temporary MDNode.
Value *Elts[] = {
GetTagConstant(VMContext, Tag),
@@ -714,9 +716,8 @@ DIType DIBuilder::createForwardDecl(unsigned Tag, StringRef Name,
MDString::get(VMContext, Name),
F,
ConstantInt::get(Type::getInt32Ty(VMContext), Line),
- // To ease transition include sizes etc of 0.
- ConstantInt::get(Type::getInt32Ty(VMContext), 0),
- ConstantInt::get(Type::getInt32Ty(VMContext), 0),
+ ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
+ ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
ConstantInt::get(Type::getInt32Ty(VMContext), 0),
ConstantInt::get(Type::getInt32Ty(VMContext),
DIDescriptor::FlagFwdDecl),
diff --git a/lib/Target/TargetData.cpp b/lib/VMCore/DataLayout.cpp
index 0040147022..3f75069a60 100644
--- a/lib/Target/TargetData.cpp
+++ b/lib/VMCore/DataLayout.cpp
@@ -1,4 +1,4 @@
-//===-- TargetData.cpp - Data size & alignment routines --------------------==//
+//===-- DataLayout.cpp - Data size & alignment routines --------------------==//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines target properties related to datatype size/offset/alignment
+// This file defines layout properties related to datatype size/offset/alignment
// information.
//
// This structure should be created once, filled in if the defaults are not
@@ -16,7 +16,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
@@ -31,17 +31,17 @@
#include <cstdlib>
using namespace llvm;
-// Handle the Pass registration stuff necessary to use TargetData's.
+// Handle the Pass registration stuff necessary to use DataLayout's.
// Register the default SparcV9 implementation...
-INITIALIZE_PASS(TargetData, "targetdata", "Target Data Layout", false, true)
-char TargetData::ID = 0;
+INITIALIZE_PASS(DataLayout, "datalayout", "Data Layout", false, true)
+char DataLayout::ID = 0;
//===----------------------------------------------------------------------===//
// Support for StructLayout
//===----------------------------------------------------------------------===//
-StructLayout::StructLayout(StructType *ST, const TargetData &TD) {
+StructLayout::StructLayout(StructType *ST, const DataLayout &TD) {
assert(!ST->isOpaque() && "Cannot get layout of opaque structs");
StructAlignment = 0;
StructSize = 0;
@@ -54,7 +54,7 @@ StructLayout::StructLayout(StructType *ST, const TargetData &TD) {
// Add padding if necessary to align the data element properly.
if ((StructSize & (TyAlign-1)) != 0)
- StructSize = TargetData::RoundUpAlignment(StructSize, TyAlign);
+ StructSize = DataLayout::RoundUpAlignment(StructSize, TyAlign);
// Keep track of maximum alignment constraint.
StructAlignment = std::max(TyAlign, StructAlignment);
@@ -69,7 +69,7 @@ StructLayout::StructLayout(StructType *ST, const TargetData &TD) {
// Add padding to the end of the struct so that it could be put in an array
// and all array elements would be aligned correctly.
if ((StructSize & (StructAlignment-1)) != 0)
- StructSize = TargetData::RoundUpAlignment(StructSize, StructAlignment);
+ StructSize = DataLayout::RoundUpAlignment(StructSize, StructAlignment);
}
@@ -94,14 +94,14 @@ unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
}
//===----------------------------------------------------------------------===//
-// TargetAlignElem, TargetAlign support
+// LayoutAlignElem, LayoutAlign support
//===----------------------------------------------------------------------===//
-TargetAlignElem
-TargetAlignElem::get(AlignTypeEnum align_type, unsigned abi_align,
+LayoutAlignElem
+LayoutAlignElem::get(AlignTypeEnum align_type, unsigned abi_align,
unsigned pref_align, uint32_t bit_width) {
assert(abi_align <= pref_align && "Preferred alignment worse than ABI!");
- TargetAlignElem retval;
+ LayoutAlignElem retval;
retval.AlignType = align_type;
retval.ABIAlign = abi_align;
retval.PrefAlign = pref_align;
@@ -110,18 +110,46 @@ TargetAlignElem::get(AlignTypeEnum align_type, unsigned abi_align,
}
bool
-TargetAlignElem::operator==(const TargetAlignElem &rhs) const {
+LayoutAlignElem::operator==(const LayoutAlignElem &rhs) const {
return (AlignType == rhs.AlignType
&& ABIAlign == rhs.ABIAlign
&& PrefAlign == rhs.PrefAlign
&& TypeBitWidth == rhs.TypeBitWidth);
}
-const TargetAlignElem
-TargetData::InvalidAlignmentElem = { (AlignTypeEnum)0xFF, 0, 0, 0 };
+const LayoutAlignElem
+DataLayout::InvalidAlignmentElem =
+ LayoutAlignElem::get((AlignTypeEnum) -1, 0, 0, 0);
//===----------------------------------------------------------------------===//
-// TargetData Class Implementation
+// PointerAlignElem, PointerAlign support
+//===----------------------------------------------------------------------===//
+
+PointerAlignElem
+PointerAlignElem::get(uint32_t addr_space, unsigned abi_align,
+ unsigned pref_align, uint32_t bit_width) {
+ assert(abi_align <= pref_align && "Preferred alignment worse than ABI!");
+ PointerAlignElem retval;
+ retval.AddressSpace = addr_space;
+ retval.ABIAlign = abi_align;
+ retval.PrefAlign = pref_align;
+ retval.TypeBitWidth = bit_width;
+ return retval;
+}
+
+bool
+PointerAlignElem::operator==(const PointerAlignElem &rhs) const {
+ return (ABIAlign == rhs.ABIAlign
+ && AddressSpace == rhs.AddressSpace
+ && PrefAlign == rhs.PrefAlign
+ && TypeBitWidth == rhs.TypeBitWidth);
+}
+
+const PointerAlignElem
+DataLayout::InvalidPointerElem = PointerAlignElem::get(~0U, 0U, 0U, 0U);
+
+//===----------------------------------------------------------------------===//
+// DataLayout Class Implementation
//===----------------------------------------------------------------------===//
/// getInt - Get an integer ignoring errors.
@@ -131,14 +159,11 @@ static int getInt(StringRef R) {
return Result;
}
-void TargetData::init() {
- initializeTargetDataPass(*PassRegistry::getPassRegistry());
+void DataLayout::init() {
+ initializeDataLayoutPass(*PassRegistry::getPassRegistry());
LayoutMap = 0;
LittleEndian = false;
- PointerMemSize = 8;
- PointerABIAlign = 8;
- PointerPrefAlign = PointerABIAlign;
StackNaturalAlign = 0;
// Default alignments
@@ -154,9 +179,10 @@ void TargetData::init() {
setAlignment(VECTOR_ALIGN, 8, 8, 64); // v2i32, v1i64, ...
setAlignment(VECTOR_ALIGN, 16, 16, 128); // v16i8, v8i16, v4i32, ...
setAlignment(AGGREGATE_ALIGN, 0, 8, 0); // struct
+ setPointerAlignment(0, 8, 8, 8);
}
-std::string TargetData::parseSpecifier(StringRef Desc, TargetData *td) {
+std::string DataLayout::parseSpecifier(StringRef Desc, DataLayout *td) {
if (td)
td->init();
@@ -185,13 +211,16 @@ std::string TargetData::parseSpecifier(StringRef Desc, TargetData *td) {
td->LittleEndian = true;
break;
case 'p': {
- // Pointer size.
+ int AddrSpace = 0;
+ if (Specifier.size() > 1) {
+ AddrSpace = getInt(Specifier.substr(1));
+ if (AddrSpace < 0 || AddrSpace > (1 << 24))
+ return "Invalid address space, must be a positive 24bit integer";
+ }
Split = Token.split(':');
int PointerMemSizeBits = getInt(Split.first);
if (PointerMemSizeBits < 0 || PointerMemSizeBits % 8 != 0)
return "invalid pointer size, must be a positive 8-bit multiple";
- if (td)
- td->PointerMemSize = PointerMemSizeBits / 8;
// Pointer ABI alignment.
Split = Split.second.split(':');
@@ -200,8 +229,6 @@ std::string TargetData::parseSpecifier(StringRef Desc, TargetData *td) {
return "invalid pointer ABI alignment, "
"must be a positive 8-bit multiple";
}
- if (td)
- td->PointerABIAlign = PointerABIAlignBits / 8;
// Pointer preferred alignment.
Split = Split.second.split(':');
@@ -210,11 +237,12 @@ std::string TargetData::parseSpecifier(StringRef Desc, TargetData *td) {
return "invalid pointer preferred alignment, "
"must be a positive 8-bit multiple";
}
- if (td) {
- td->PointerPrefAlign = PointerPrefAlignBits / 8;
- if (td->PointerPrefAlign == 0)
- td->PointerPrefAlign = td->PointerABIAlign;
- }
+
+ if (PointerPrefAlignBits == 0)
+ PointerPrefAlignBits = PointerABIAlignBits;
+ if (td)
+ td->setPointerAlignment(AddrSpace, PointerABIAlignBits/8,
+ PointerPrefAlignBits/8, PointerMemSizeBits/8);
break;
}
case 'i':
@@ -256,7 +284,7 @@ std::string TargetData::parseSpecifier(StringRef Desc, TargetData *td) {
unsigned PrefAlign = PrefAlignBits / 8;
if (PrefAlign == 0)
PrefAlign = ABIAlign;
-
+
if (td)
td->setAlignment(AlignType, ABIAlign, PrefAlign, Size);
break;
@@ -266,8 +294,8 @@ std::string TargetData::parseSpecifier(StringRef Desc, TargetData *td) {
do {
int Width = getInt(Specifier);
if (Width <= 0) {
- return std::string("invalid native integer size \'") + Specifier.str() +
- "\', must be a positive integer.";
+ return std::string("invalid native integer size \'") +
+ Specifier.str() + "\', must be a positive integer.";
}
if (td && Width != 0)
td->LegalIntWidths.push_back(Width);
@@ -298,26 +326,26 @@ std::string TargetData::parseSpecifier(StringRef Desc, TargetData *td) {
///
/// @note This has to exist, because this is a pass, but it should never be
/// used.
-TargetData::TargetData() : ImmutablePass(ID) {
- report_fatal_error("Bad TargetData ctor used. "
- "Tool did not specify a TargetData to use?");
+DataLayout::DataLayout() : ImmutablePass(ID) {
+ report_fatal_error("Bad DataLayout ctor used. "
+ "Tool did not specify a DataLayout to use?");
}
-TargetData::TargetData(const Module *M)
+DataLayout::DataLayout(const Module *M)
: ImmutablePass(ID) {
std::string errMsg = parseSpecifier(M->getDataLayout(), this);
- assert(errMsg == "" && "Module M has malformed target data layout string.");
+ assert(errMsg == "" && "Module M has malformed data layout string.");
(void)errMsg;
}
void
-TargetData::setAlignment(AlignTypeEnum align_type, unsigned abi_align,
+DataLayout::setAlignment(AlignTypeEnum align_type, unsigned abi_align,
unsigned pref_align, uint32_t bit_width) {
assert(abi_align <= pref_align && "Preferred alignment worse than ABI!");
assert(pref_align < (1 << 16) && "Alignment doesn't fit in bitfield");
assert(bit_width < (1 << 24) && "Bit width doesn't fit in bitfield");
for (unsigned i = 0, e = Alignments.size(); i != e; ++i) {
- if (Alignments[i].AlignType == align_type &&
+ if (Alignments[i].AlignType == (unsigned)align_type &&
Alignments[i].TypeBitWidth == bit_width) {
// Update the abi, preferred alignments.
Alignments[i].ABIAlign = abi_align;
@@ -326,20 +354,35 @@ TargetData::setAlignment(AlignTypeEnum align_type, unsigned abi_align,
}
}
- Alignments.push_back(TargetAlignElem::get(align_type, abi_align,
+ Alignments.push_back(LayoutAlignElem::get(align_type, abi_align,
pref_align, bit_width));
}
+void
+DataLayout::setPointerAlignment(uint32_t addr_space, unsigned abi_align,
+ unsigned pref_align, uint32_t bit_width) {
+ assert(abi_align <= pref_align && "Preferred alignment worse than ABI!");
+ DenseMap<unsigned,PointerAlignElem>::iterator val = Pointers.find(addr_space);
+ if (val == Pointers.end()) {
+ Pointers[addr_space] = PointerAlignElem::get(addr_space,
+ abi_align, pref_align, bit_width);
+ } else {
+ val->second.ABIAlign = abi_align;
+ val->second.PrefAlign = pref_align;
+ val->second.TypeBitWidth = bit_width;
+ }
+}
+
/// getAlignmentInfo - Return the alignment (either ABI if ABIInfo = true or
-/// preferred if ABIInfo = false) the target wants for the specified datatype.
-unsigned TargetData::getAlignmentInfo(AlignTypeEnum AlignType,
+/// preferred if ABIInfo = false) the layout wants for the specified datatype.
+unsigned DataLayout::getAlignmentInfo(AlignTypeEnum AlignType,
uint32_t BitWidth, bool ABIInfo,
Type *Ty) const {
// Check to see if we have an exact match and remember the best match we see.
int BestMatchIdx = -1;
int LargestInt = -1;
for (unsigned i = 0, e = Alignments.size(); i != e; ++i) {
- if (Alignments[i].AlignType == AlignType &&
+ if (Alignments[i].AlignType == (unsigned)AlignType &&
Alignments[i].TypeBitWidth == BitWidth)
return ABIInfo ? Alignments[i].ABIAlign : Alignments[i].PrefAlign;
@@ -412,11 +455,11 @@ public:
} // end anonymous namespace
-TargetData::~TargetData() {
+DataLayout::~DataLayout() {
delete static_cast<StructLayoutMap*>(LayoutMap);
}
-const StructLayout *TargetData::getStructLayout(StructType *Ty) const {
+const StructLayout *DataLayout::getStructLayout(StructType *Ty) const {
if (!LayoutMap)
LayoutMap = new StructLayoutMap();
@@ -439,17 +482,35 @@ const StructLayout *TargetData::getStructLayout(StructType *Ty) const {
return L;
}
-std::string TargetData::getStringRepresentation() const {
+std::string DataLayout::getStringRepresentation() const {
std::string Result;
raw_string_ostream OS(Result);
- OS << (LittleEndian ? "e" : "E")
- << "-p:" << PointerMemSize*8 << ':' << PointerABIAlign*8
- << ':' << PointerPrefAlign*8
- << "-S" << StackNaturalAlign*8;
+ OS << (LittleEndian ? "e" : "E");
+ SmallVector<unsigned, 8> addrSpaces;
+ // Lets get all of the known address spaces and sort them
+ // into increasing order so that we can emit the string
+ // in a cleaner format.
+ for (DenseMap<unsigned, PointerAlignElem>::const_iterator
+ pib = Pointers.begin(), pie = Pointers.end();
+ pib != pie; ++pib) {
+ addrSpaces.push_back(pib->first);
+ }
+ std::sort(addrSpaces.begin(), addrSpaces.end());
+ for (SmallVector<unsigned, 8>::iterator asb = addrSpaces.begin(),
+ ase = addrSpaces.end(); asb != ase; ++asb) {
+ const PointerAlignElem &PI = Pointers.find(*asb)->second;
+ OS << "-p";
+ if (PI.AddressSpace) {
+ OS << PI.AddressSpace;
+ }
+ OS << ":" << PI.TypeBitWidth*8 << ':' << PI.ABIAlign*8
+ << ':' << PI.PrefAlign*8;
+ }
+ OS << "-S" << StackNaturalAlign*8;
for (unsigned i = 0, e = Alignments.size(); i != e; ++i) {
- const TargetAlignElem &AI = Alignments[i];
+ const LayoutAlignElem &AI = Alignments[i];
OS << '-' << (char)AI.AlignType << AI.TypeBitWidth << ':'
<< AI.ABIAlign*8 << ':' << AI.PrefAlign*8;
}
@@ -464,12 +525,15 @@ std::string TargetData::getStringRepresentation() const {
}
-uint64_t TargetData::getTypeSizeInBits(Type *Ty) const {
+uint64_t DataLayout::getTypeSizeInBits(Type *Ty) const {
assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
switch (Ty->getTypeID()) {
case Type::LabelTyID:
- case Type::PointerTyID:
- return getPointerSizeInBits();
+ return getPointerSizeInBits(0);
+ case Type::PointerTyID: {
+ unsigned AS = dyn_cast<PointerType>(Ty)->getAddressSpace();
+ return getPointerSizeInBits(AS);
+ }
case Type::ArrayTyID: {
ArrayType *ATy = cast<ArrayType>(Ty);
return getTypeAllocSizeInBits(ATy->getElementType())*ATy->getNumElements();
@@ -498,7 +562,7 @@ uint64_t TargetData::getTypeSizeInBits(Type *Ty) const {
case Type::VectorTyID:
return cast<VectorType>(Ty)->getBitWidth();
default:
- llvm_unreachable("TargetData::getTypeSizeInBits(): Unsupported type");
+ llvm_unreachable("DataLayout::getTypeSizeInBits(): Unsupported type");
}
}
@@ -510,17 +574,22 @@ uint64_t TargetData::getTypeSizeInBits(Type *Ty) const {
Get the ABI (\a abi_or_pref == true) or preferred alignment (\a abi_or_pref
== false) for the requested type \a Ty.
*/
-unsigned TargetData::getAlignment(Type *Ty, bool abi_or_pref) const {
+unsigned DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
int AlignType = -1;
assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
switch (Ty->getTypeID()) {
// Early escape for the non-numeric types.
case Type::LabelTyID:
- case Type::PointerTyID:
return (abi_or_pref
- ? getPointerABIAlignment()
- : getPointerPrefAlignment());
+ ? getPointerABIAlignment(0)
+ : getPointerPrefAlignment(0));
+ case Type::PointerTyID: {
+ unsigned AS = dyn_cast<PointerType>(Ty)->getAddressSpace();
+ return (abi_or_pref
+ ? getPointerABIAlignment(AS)
+ : getPointerPrefAlignment(AS));
+ }
case Type::ArrayTyID:
return getAlignment(cast<ArrayType>(Ty)->getElementType(), abi_or_pref);
@@ -560,18 +629,18 @@ unsigned TargetData::getAlignment(Type *Ty, bool abi_or_pref) const {
abi_or_pref, Ty);
}
-unsigned TargetData::getABITypeAlignment(Type *Ty) const {
+unsigned DataLayout::getABITypeAlignment(Type *Ty) const {
return getAlignment(Ty, true);
}
/// getABIIntegerTypeAlignment - Return the minimum ABI-required alignment for
/// an integer type of the specified bitwidth.
-unsigned TargetData::getABIIntegerTypeAlignment(unsigned BitWidth) const {
+unsigned DataLayout::getABIIntegerTypeAlignment(unsigned BitWidth) const {
return getAlignmentInfo(INTEGER_ALIGN, BitWidth, true, 0);
}
-unsigned TargetData::getCallFrameTypeAlignment(Type *Ty) const {
+unsigned DataLayout::getCallFrameTypeAlignment(Type *Ty) const {
for (unsigned i = 0, e = Alignments.size(); i != e; ++i)
if (Alignments[i].AlignType == STACK_ALIGN)
return Alignments[i].ABIAlign;
@@ -579,11 +648,11 @@ unsigned TargetData::getCallFrameTypeAlignment(Type *Ty) const {
return getABITypeAlignment(Ty);
}
-unsigned TargetData::getPrefTypeAlignment(Type *Ty) const {
+unsigned DataLayout::getPrefTypeAlignment(Type *Ty) const {
return getAlignment(Ty, false);
}
-unsigned TargetData::getPreferredTypeAlignmentShift(Type *Ty) const {
+unsigned DataLayout::getPreferredTypeAlignmentShift(Type *Ty) const {
unsigned Align = getPrefTypeAlignment(Ty);
assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
return Log2_32(Align);
@@ -591,12 +660,13 @@ unsigned TargetData::getPreferredTypeAlignmentShift(Type *Ty) const {
/// getIntPtrType - Return an unsigned integer type that is the same size or
/// greater to the host pointer size.
-IntegerType *TargetData::getIntPtrType(LLVMContext &C) const {
- return IntegerType::get(C, getPointerSizeInBits());
+IntegerType *DataLayout::getIntPtrType(LLVMContext &C,
+ unsigned AddressSpace) const {
+ return IntegerType::get(C, getPointerSizeInBits(AddressSpace));
}
-uint64_t TargetData::getIndexedOffset(Type *ptrTy,
+uint64_t DataLayout::getIndexedOffset(Type *ptrTy,
ArrayRef<Value *> Indices) const {
Type *Ty = ptrTy;
assert(Ty->isPointerTy() && "Illegal argument for getIndexedOffset()");
@@ -636,7 +706,7 @@ uint64_t TargetData::getIndexedOffset(Type *ptrTy,
/// getPreferredAlignment - Return the preferred alignment of the specified
/// global. This includes an explicitly requested alignment (if the global
/// has one).
-unsigned TargetData::getPreferredAlignment(const GlobalVariable *GV) const {
+unsigned DataLayout::getPreferredAlignment(const GlobalVariable *GV) const {
Type *ElemType = GV->getType()->getElementType();
unsigned Alignment = getPrefTypeAlignment(ElemType);
unsigned GVAlignment = GV->getAlignment();
@@ -660,6 +730,6 @@ unsigned TargetData::getPreferredAlignment(const GlobalVariable *GV) const {
/// getPreferredAlignmentLog - Return the preferred alignment of the
/// specified global, returned in log form. This includes an explicitly
/// requested alignment (if the global has one).
-unsigned TargetData::getPreferredAlignmentLog(const GlobalVariable *GV) const {
+unsigned DataLayout::getPreferredAlignmentLog(const GlobalVariable *GV) const {
return Log2_32(getPreferredAlignment(GV));
}
diff --git a/lib/VMCore/DebugInfo.cpp b/lib/VMCore/DebugInfo.cpp
index c8f8f7d67b..3029ce2734 100644
--- a/lib/VMCore/DebugInfo.cpp
+++ b/lib/VMCore/DebugInfo.cpp
@@ -111,6 +111,16 @@ Function *DIDescriptor::getFunctionField(unsigned Elt) const {
return 0;
}
+void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) {
+ if (DbgNode == 0)
+ return;
+
+ if (Elt < DbgNode->getNumOperands()) {
+ MDNode *Node = const_cast<MDNode*>(DbgNode);
+ Node->replaceOperandWith(Elt, F);
+ }
+}
+
unsigned DIVariable::getNumAddrElements() const {
if (getVersion() <= LLVMDebugVersion8)
return DbgNode->getNumOperands()-6;
diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp
index 012d27603a..5c2a03ce09 100644
--- a/lib/VMCore/Function.cpp
+++ b/lib/VMCore/Function.cpp
@@ -78,7 +78,8 @@ unsigned Argument::getArgNo() const {
/// in its containing function.
bool Argument::hasByValAttr() const {
if (!getType()->isPointerTy()) return false;
- return getParent()->getParamAttributes(getArgNo()+1).hasByValAttr();
+ return getParent()->getParamAttributes(getArgNo()+1).
+ hasAttribute(Attributes::ByVal);
}
unsigned Argument::getParamAlignment() const {
@@ -91,21 +92,24 @@ unsigned Argument::getParamAlignment() const {
/// it in its containing function.
bool Argument::hasNestAttr() const {
if (!getType()->isPointerTy()) return false;
- return getParent()->getParamAttributes(getArgNo()+1).hasNestAttr();
+ return getParent()->getParamAttributes(getArgNo()+1).
+ hasAttribute(Attributes::Nest);
}
/// hasNoAliasAttr - Return true if this argument has the noalias attribute on
/// it in its containing function.
bool Argument::hasNoAliasAttr() const {
if (!getType()->isPointerTy()) return false;
- return getParent()->getParamAttributes(getArgNo()+1).hasNoAliasAttr();
+ return getParent()->getParamAttributes(getArgNo()+1).
+ hasAttribute(Attributes::NoAlias);
}
/// hasNoCaptureAttr - Return true if this argument has the nocapture attribute
/// on it in its containing function.
bool Argument::hasNoCaptureAttr() const {
if (!getType()->isPointerTy()) return false;
- return getParent()->getParamAttributes(getArgNo()+1).hasNoCaptureAttr();
+ return getParent()->getParamAttributes(getArgNo()+1).
+ hasAttribute(Attributes::NoCapture);
}
/// hasSRetAttr - Return true if this argument has the sret attribute on
@@ -114,7 +118,8 @@ bool Argument::hasStructRetAttr() const {
if (!getType()->isPointerTy()) return false;
if (this != getParent()->arg_begin())
return false; // StructRet param must be first param
- return getParent()->getParamAttributes(1).hasStructRetAttr();
+ return getParent()->getParamAttributes(1).
+ hasAttribute(Attributes::StructRet);
}
/// addAttr - Add a Attribute to an argument
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index d5b756dac0..74c0c6e1d9 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -342,11 +342,19 @@ void CallInst::removeAttribute(unsigned i, Attributes attr) {
setAttributes(PAL);
}
-bool CallInst::paramHasAttr(unsigned i, Attributes attr) const {
- if (AttributeList.paramHasAttr(i, attr))
+bool CallInst::hasFnAttr(Attributes::AttrVal A) const {
+ if (AttributeList.getParamAttributes(~0U).hasAttribute(A))
return true;
if (const Function *F = getCalledFunction())
- return F->paramHasAttr(i, attr);
+ return F->getParamAttributes(~0U).hasAttribute(A);
+ return false;
+}
+
+bool CallInst::paramHasAttr(unsigned i, Attributes::AttrVal A) const {
+ if (AttributeList.getParamAttributes(i).hasAttribute(A))
+ return true;
+ if (const Function *F = getCalledFunction())
+ return F->getParamAttributes(i).hasAttribute(A);
return false;
}
@@ -562,11 +570,19 @@ void InvokeInst::setSuccessorV(unsigned idx, BasicBlock *B) {
return setSuccessor(idx, B);
}
-bool InvokeInst::paramHasAttr(unsigned i, Attributes attr) const {
- if (AttributeList.paramHasAttr(i, attr))
+bool InvokeInst::hasFnAttr(Attributes::AttrVal A) const {
+ if (AttributeList.getParamAttributes(~0U).hasAttribute(A))
+ return true;
+ if (const Function *F = getCalledFunction())
+ return F->getParamAttributes(~0U).hasAttribute(A);
+ return false;
+}
+
+bool InvokeInst::paramHasAttr(unsigned i, Attributes::AttrVal A) const {
+ if (AttributeList.getParamAttributes(i).hasAttribute(A))
return true;
if (const Function *F = getCalledFunction())
- return F->paramHasAttr(i, attr);
+ return F->getParamAttributes(i).hasAttribute(A);
return false;
}
diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h
index ee31814c05..524f7e54bb 100644
--- a/lib/VMCore/LLVMContextImpl.h
+++ b/lib/VMCore/LLVMContextImpl.h
@@ -16,9 +16,9 @@
#define LLVM_LLVMCONTEXT_IMPL_H
#include "llvm/LLVMContext.h"
-#include "AttributesImpl.h"
#include "ConstantsContext.h"
#include "LeaksContext.h"
+#include "llvm/AttributesImpl.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Metadata.h"
diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp
index d8711082ff..8d0720dc12 100644
--- a/lib/VMCore/Value.cpp
+++ b/lib/VMCore/Value.cpp
@@ -394,7 +394,7 @@ static bool isDereferenceablePointer(const Value *V,
// It's also not always safe to follow a bitcast, for example:
// bitcast i8* (alloca i8) to i32*
// would result in a 4-byte load from a 1-byte alloca. Some cases could
- // be handled using TargetData to check sizes and alignments though.
+ // be handled using DataLayout to check sizes and alignments though.
// These are obviously ok.
if (isa<AllocaInst>(V)) return true;
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 292456ab63..53744b4869 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -526,40 +526,59 @@ void Verifier::visitMDNode(MDNode &MD, Function *F) {
// value of the specified type. The value V is printed in error messages.
void Verifier::VerifyParameterAttrs(Attributes Attrs, Type *Ty,
bool isReturnValue, const Value *V) {
- if (Attrs == Attribute::None)
+ if (!Attrs.hasAttributes())
return;
- Attributes FnCheckAttr = Attrs & Attribute::FunctionOnly;
- Assert1(!FnCheckAttr, "Attribute " + FnCheckAttr.getAsString() +
- " only applies to the function!", V);
-
- if (isReturnValue) {
- Attributes RetI = Attrs & Attribute::ParameterOnly;
- Assert1(!RetI, "Attribute " + RetI.getAsString() +
- " does not apply to return values!", V);
- }
-
- for (unsigned i = 0;
- i < array_lengthof(Attribute::MutuallyIncompatible); ++i) {
- Attributes MutI = Attrs & Attribute::MutuallyIncompatible[i];
- Assert1(MutI.isEmptyOrSingleton(), "Attributes " +
- MutI.getAsString() + " are incompatible!", V);
- }
+ Assert1(!Attrs.hasFunctionOnlyAttrs(),
+ "Some attributes in '" + Attrs.getAsString() +
+ "' only apply to functions!", V);
+
+ if (isReturnValue)
+ Assert1(!Attrs.hasParameterOnlyAttrs(),
+ "Attributes 'byval', 'nest', 'sret', and 'nocapture' "
+ "do not apply to return values!", V);
+
+ // Check for mutually incompatible attributes.
+ Assert1(!((Attrs.hasAttribute(Attributes::ByVal) &&
+ Attrs.hasAttribute(Attributes::Nest)) ||
+ (Attrs.hasAttribute(Attributes::ByVal) &&
+ Attrs.hasAttribute(Attributes::StructRet)) ||
+ (Attrs.hasAttribute(Attributes::Nest) &&
+ Attrs.hasAttribute(Attributes::StructRet))), "Attributes "
+ "'byval, nest, and sret' are incompatible!", V);
+
+ Assert1(!((Attrs.hasAttribute(Attributes::ByVal) &&
+ Attrs.hasAttribute(Attributes::Nest)) ||
+ (Attrs.hasAttribute(Attributes::ByVal) &&
+ Attrs.hasAttribute(Attributes::InReg)) ||
+ (Attrs.hasAttribute(Attributes::Nest) &&
+ Attrs.hasAttribute(Attributes::InReg))), "Attributes "
+ "'byval, nest, and inreg' are incompatible!", V);
+
+ Assert1(!(Attrs.hasAttribute(Attributes::ZExt) &&
+ Attrs.hasAttribute(Attributes::SExt)), "Attributes "
+ "'zeroext and signext' are incompatible!", V);
+
+ Assert1(!(Attrs.hasAttribute(Attributes::ReadNone) &&
+ Attrs.hasAttribute(Attributes::ReadOnly)), "Attributes "
+ "'readnone and readonly' are incompatible!", V);
+
+ Assert1(!(Attrs.hasAttribute(Attributes::NoInline) &&
+ Attrs.hasAttribute(Attributes::AlwaysInline)), "Attributes "
+ "'noinline and alwaysinline' are incompatible!", V);
Attributes TypeI = Attrs & Attributes::typeIncompatible(Ty);
Assert1(!TypeI, "Wrong type for attribute " +
TypeI.getAsString(), V);
- Attributes ByValI = Attrs & Attribute::ByVal;
- if (PointerType *PTy = dyn_cast<PointerType>(Ty)) {
- Assert1(!ByValI || PTy->getElementType()->isSized(),
- "Attribute " + ByValI.getAsString() +
- " does not support unsized types!", V);
- } else {
- Assert1(!ByValI,
- "Attribute " + ByValI.getAsString() +
- " only applies to parameters with pointer type!", V);
- }
+ if (PointerType *PTy = dyn_cast<PointerType>(Ty))
+ Assert1(!Attrs.hasAttribute(Attributes::ByVal) ||
+ PTy->getElementType()->isSized(),
+ "Attribute 'byval' does not support unsized types!", V);
+ else
+ Assert1(!Attrs.hasAttribute(Attributes::ByVal),
+ "Attribute 'byval' only applies to parameters with pointer type!",
+ V);
}
// VerifyFunctionAttrs - Check parameter attributes against a function type.
@@ -585,26 +604,50 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT,
VerifyParameterAttrs(Attr.Attrs, Ty, Attr.Index == 0, V);
- if (Attr.Attrs.hasNestAttr()) {
+ if (Attr.Attrs.hasAttribute(Attributes::Nest)) {
Assert1(!SawNest, "More than one parameter has attribute nest!", V);
SawNest = true;
}
- if (Attr.Attrs.hasStructRetAttr())
+ if (Attr.Attrs.hasAttribute(Attributes::StructRet))
Assert1(Attr.Index == 1, "Attribute sret not on first parameter!", V);
}
Attributes FAttrs = Attrs.getFnAttributes();
- Attributes NotFn = FAttrs & (~Attribute::FunctionOnly);
- Assert1(!NotFn, "Attribute " + NotFn.getAsString() +
- " does not apply to the function!", V);
-
- for (unsigned i = 0;
- i < array_lengthof(Attribute::MutuallyIncompatible); ++i) {
- Attributes MutI = FAttrs & Attribute::MutuallyIncompatible[i];
- Assert1(MutI.isEmptyOrSingleton(), "Attributes " +
- MutI.getAsString() + " are incompatible!", V);
- }
+ Attributes::Builder NotFn(FAttrs);
+ NotFn.removeFunctionOnlyAttrs();
+ Assert1(!NotFn.hasAttributes(), "Attributes '" +
+ Attributes::get(NotFn).getAsString() +
+ "' do not apply to the function!", V);
+
+ // Check for mutually incompatible attributes.
+ Assert1(!((FAttrs.hasAttribute(Attributes::ByVal) &&
+ FAttrs.hasAttribute(Attributes::Nest)) ||
+ (FAttrs.hasAttribute(Attributes::ByVal) &&
+ FAttrs.hasAttribute(Attributes::StructRet)) ||
+ (FAttrs.hasAttribute(Attributes::Nest) &&
+ FAttrs.hasAttribute(Attributes::StructRet))), "Attributes "
+ "'byval, nest, and sret' are incompatible!", V);
+
+ Assert1(!((FAttrs.hasAttribute(Attributes::ByVal) &&
+ FAttrs.hasAttribute(Attributes::Nest)) ||
+ (FAttrs.hasAttribute(Attributes::ByVal) &&
+ FAttrs.hasAttribute(Attributes::InReg)) ||
+ (FAttrs.hasAttribute(Attributes::Nest) &&
+ FAttrs.hasAttribute(Attributes::InReg))), "Attributes "
+ "'byval, nest, and inreg' are incompatible!", V);
+
+ Assert1(!(FAttrs.hasAttribute(Attributes::ZExt) &&
+ FAttrs.hasAttribute(Attributes::SExt)), "Attributes "
+ "'zeroext and signext' are incompatible!", V);
+
+ Assert1(!(FAttrs.hasAttribute(Attributes::ReadNone) &&
+ FAttrs.hasAttribute(Attributes::ReadOnly)), "Attributes "
+ "'readnone and readonly' are incompatible!", V);
+
+ Assert1(!(FAttrs.hasAttribute(Attributes::NoInline) &&
+ FAttrs.hasAttribute(Attributes::AlwaysInline)), "Attributes "
+ "'noinline and alwaysinline' are incompatible!", V);
}
static bool VerifyAttributeCount(const AttrListPtr &Attrs, unsigned Params) {
@@ -1170,9 +1213,8 @@ void Verifier::VerifyCallSite(CallSite CS) {
VerifyParameterAttrs(Attr, CS.getArgument(Idx-1)->getType(), false, I);
- Attributes VArgI = Attr & Attribute::VarArgsIncompatible;
- Assert1(!VArgI, "Attribute " + VArgI.getAsString() +
- " cannot be used for vararg call arguments!", I);
+ Assert1(!Attr.hasIncompatibleWithVarArgsAttrs(),
+ "Attribute 'sret' cannot be used for vararg call arguments!", I);
}
// Verify that there's no metadata unless it's a direct call to an intrinsic.
diff --git a/projects/sample/Makefile.llvm.rules b/projects/sample/Makefile.llvm.rules
index a6553020f8..7ed1c1b4ed 100644
--- a/projects/sample/Makefile.llvm.rules
+++ b/projects/sample/Makefile.llvm.rules
@@ -1437,7 +1437,7 @@ install-local::
uninstall-local::
$(Echo) Uninstall circumvented with NO_INSTALL
else
-DestTool = $(DESTDIR)$(PROJ_bindir)/$(TOOLEXENAME)
+DestTool = $(DESTDIR)$(PROJ_bindir)/$(program_prefix)$(TOOLEXENAME)
install-local:: $(DestTool)
@@ -1451,7 +1451,7 @@ uninstall-local::
# TOOLALIAS install.
ifdef TOOLALIAS
-DestToolAlias = $(DESTDIR)$(PROJ_bindir)/$(TOOLALIAS)$(EXEEXT)
+DestToolAlias = $(DESTDIR)$(PROJ_bindir)/$(program_prefix)$(TOOLALIAS)$(EXEEXT)
install-local:: $(DestToolAlias)
diff --git a/runtime/libprofile/Makefile b/runtime/libprofile/Makefile
index d8511495ce..e9b220cf2f 100644
--- a/runtime/libprofile/Makefile
+++ b/runtime/libprofile/Makefile
@@ -44,8 +44,16 @@ ifeq ($(HOST_OS),Darwin)
# command line.
DARWIN_VERS := $(shell echo $(TARGET_TRIPLE) | sed 's/.*darwin\([0-9]*\).*/\1/')
ifneq ($(DARWIN_VERS),8)
- LLVMLibsOptions := $(LLVMLibsOptions) \
+ LLVMLibsOptions := $(LLVMLibsOptions) \
-Wl,-install_name \
-Wl,"@executable_path/../lib/lib$(LIBRARYNAME)$(SHLIBEXT)"
endif
+
+ # If we're doing an Apple-style build, add the LTO object path.
+ ifeq ($(RC_BUILDIT),YES)
+ ObjDir := $(shell mkdir -p ${OBJROOT}/dSYMs)
+ TempFile := $(shell mktemp ${ObjDir}/profile_rt-lto.XXXXXX)
+ LLVMLibsOptions := $(LLVMLibsOptions) \
+ -Wl,-object_path_lto -Wl,$(TempFile)
+ endif
endif
diff --git a/test/Analysis/Profiling/load-branch-weights-ifs.ll b/test/Analysis/Profiling/load-branch-weights-ifs.ll
index ddbaf96916..7ed090b7c3 100644
--- a/test/Analysis/Profiling/load-branch-weights-ifs.ll
+++ b/test/Analysis/Profiling/load-branch-weights-ifs.ll
@@ -1,6 +1,6 @@
; RUN: opt -insert-edge-profiling -o %t1 < %s
; RUN: rm -f %t1.prof_data
-; RUN: lli -load %llvmshlibdir/libprofile_rt%shlibext %t1 \
+; RUN: lli %defaultjit -load %llvmshlibdir/libprofile_rt%shlibext %t1 \
; RUN: -llvmprof-output %t1.prof_data
; RUN: opt -profile-file %t1.prof_data -profile-metadata-loader -S -o - < %s \
; RUN: | FileCheck %s
diff --git a/test/Analysis/Profiling/load-branch-weights-loops.ll b/test/Analysis/Profiling/load-branch-weights-loops.ll
index 476f377b47..9d1925a2d7 100644
--- a/test/Analysis/Profiling/load-branch-weights-loops.ll
+++ b/test/Analysis/Profiling/load-branch-weights-loops.ll
@@ -1,6 +1,6 @@
; RUN: opt -insert-edge-profiling -o %t1 < %s
; RUN: rm -f %t1.prof_data
-; RUN: lli -load %llvmshlibdir/libprofile_rt%shlibext %t1 \
+; RUN: lli %defaultjit -load %llvmshlibdir/libprofile_rt%shlibext %t1 \
; RUN: -llvmprof-output %t1.prof_data
; RUN: opt -profile-file %t1.prof_data -profile-metadata-loader -S -o - < %s \
; RUN: | FileCheck %s
diff --git a/test/Analysis/Profiling/load-branch-weights-switches.ll b/test/Analysis/Profiling/load-branch-weights-switches.ll
index be11f040a7..5587c7172b 100644
--- a/test/Analysis/Profiling/load-branch-weights-switches.ll
+++ b/test/Analysis/Profiling/load-branch-weights-switches.ll
@@ -1,6 +1,6 @@
; RUN: opt -insert-edge-profiling -o %t1 < %s
; RUN: rm -f %t1.prof_data
-; RUN: lli -load %llvmshlibdir/libprofile_rt%shlibext %t1 \
+; RUN: lli %defaultjit -load %llvmshlibdir/libprofile_rt%shlibext %t1 \
; RUN: -llvmprof-output %t1.prof_data
; RUN: opt -profile-file %t1.prof_data -profile-metadata-loader -S -o - < %s \
; RUN: | FileCheck %s
diff --git a/test/Assembler/2008-09-02-FunctionNotes2.ll b/test/Assembler/2008-09-02-FunctionNotes2.ll
index 97351e2a57..47eb011343 100644
--- a/test/Assembler/2008-09-02-FunctionNotes2.ll
+++ b/test/Assembler/2008-09-02-FunctionNotes2.ll
@@ -1,5 +1,5 @@
; Test function notes
-; RUN: not llvm-as %s -o /dev/null 2>&1 | grep "Attributes noinline alwaysinline are incompatible"
+; RUN: not llvm-as %s -o /dev/null 2>&1 | grep "Attributes 'noinline and alwaysinline' are incompatible"
define void @fn1() alwaysinline noinline {
ret void
}
diff --git a/test/Bindings/Ocaml/ipo_opts.ml b/test/Bindings/Ocaml/ipo_opts.ml
index 3a362319a7..d4537e4413 100644
--- a/test/Bindings/Ocaml/ipo_opts.ml
+++ b/test/Bindings/Ocaml/ipo_opts.ml
@@ -43,10 +43,10 @@ let test_transforms () =
ignore (build_ret (build_call fn [| |] "" b) b);
end;
- let td = TargetData.create (target_triple m) in
+ let td = DataLayout.create (target_triple m) in
ignore (PassManager.create ()
- ++ TargetData.add td
+ ++ DataLayout.add td
++ add_argument_promotion
++ add_constant_merge
++ add_dead_arg_elimination
@@ -63,7 +63,7 @@ let test_transforms () =
++ PassManager.run_module m
++ PassManager.dispose);
- TargetData.dispose td
+ DataLayout.dispose td
(*===-- Driver ------------------------------------------------------------===*)
diff --git a/test/Bindings/Ocaml/scalar_opts.ml b/test/Bindings/Ocaml/scalar_opts.ml
index 34a7a6a01b..0760dad4ad 100644
--- a/test/Bindings/Ocaml/scalar_opts.ml
+++ b/test/Bindings/Ocaml/scalar_opts.ml
@@ -38,10 +38,10 @@ let test_transforms () =
let fn = define_function "fn" fty m in
ignore (build_ret_void (builder_at_end context (entry_block fn)));
- let td = TargetData.create (target_triple m) in
+ let td = DataLayout.create (target_triple m) in
ignore (PassManager.create_function m
- ++ TargetData.add td
+ ++ DataLayout.add td
++ add_verifier
++ add_constant_propagation
++ add_sccp
@@ -78,7 +78,7 @@ let test_transforms () =
++ PassManager.finalize
++ PassManager.dispose);
- TargetData.dispose td
+ DataLayout.dispose td
(*===-- Driver ------------------------------------------------------------===*)
diff --git a/test/Bindings/Ocaml/target.ml b/test/Bindings/Ocaml/target.ml
index 1b6b71e275..7a35a790ab 100644
--- a/test/Bindings/Ocaml/target.ml
+++ b/test/Bindings/Ocaml/target.ml
@@ -33,10 +33,10 @@ let m = create_module context filename
(*===-- Target Data -------------------------------------------------------===*)
let test_target_data () =
- let td = TargetData.create (target_triple m) in
+ let td = DataLayout.create (target_triple m) in
let sty = struct_type context [| i32_type; i64_type |] in
- ignore (TargetData.as_string td);
+ ignore (DataLayout.as_string td);
ignore (byte_order td);
ignore (pointer_size td);
ignore (intptr_type td);
@@ -49,7 +49,7 @@ let test_target_data () =
ignore (element_at_offset td sty (Int64.of_int 1));
ignore (offset_of_element td sty 1);
- TargetData.dispose td
+ DataLayout.dispose td
(*===-- Driver ------------------------------------------------------------===*)
diff --git a/test/CodeGen/ARM/coalesce-subregs.ll b/test/CodeGen/ARM/coalesce-subregs.ll
index 8d7ded5be0..6e1f17dced 100644
--- a/test/CodeGen/ARM/coalesce-subregs.ll
+++ b/test/CodeGen/ARM/coalesce-subregs.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mcpu=cortex-a9 -new-coalescer | FileCheck %s
+; RUN: llc < %s -mcpu=cortex-a9 -verify-coalescing | FileCheck %s
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32"
target triple = "thumbv7-apple-ios0.0.0"
@@ -189,3 +189,28 @@ if.end: ; preds = %entry, %if.then
declare <4 x float> @llvm.arm.neon.vld1.v4f32(i8*, i32) nounwind readonly
declare void @llvm.arm.neon.vst1.v4f32(i8*, <4 x float>, i32) nounwind
+
+; CHECK: pr13999
+define void @pr13999() nounwind readonly {
+entry:
+ br i1 true, label %outer_loop, label %loop.end
+
+outer_loop:
+ %d = phi double [ 0.0, %entry ], [ %add, %after_inner_loop ]
+ %0 = insertelement <2 x double> <double 0.0, double 0.0>, double %d, i32 0
+ br i1 undef, label %after_inner_loop, label %inner_loop
+
+inner_loop:
+ br i1 true, label %after_inner_loop, label %inner_loop
+
+after_inner_loop:
+ %1 = phi <2 x double> [ %0, %outer_loop ], [ <double 0.0, double 0.0>,
+%inner_loop ]
+ %2 = extractelement <2 x double> %1, i32 1
+ %add = fadd double 1.0, %2
+ br i1 false, label %loop.end, label %outer_loop
+
+loop.end:
+ %d.end = phi double [ 0.0, %entry ], [ %add, %after_inner_loop ]
+ ret void
+}
diff --git a/test/CodeGen/ARM/darwin-section-order.ll b/test/CodeGen/ARM/darwin-section-order.ll
new file mode 100644
index 0000000000..701028c0a5
--- /dev/null
+++ b/test/CodeGen/ARM/darwin-section-order.ll
@@ -0,0 +1,21 @@
+; RUN: llc < %s -mtriple=armv7-apple-darwin | FileCheck %s
+
+; CHECK: .section __TEXT,__text,regular,pure_instructions
+; CHECK: .section __TEXT,myprecious
+; CHECK: .section __TEXT,__textcoal_nt,coalesced,pure_instructions
+; CHECK: .section __TEXT,__const_coal,coalesced
+; CHECK: .section __TEXT,__picsymbolstub4,symbol_stubs,none,16
+; CHECK: .section __TEXT,__StaticInit,regular,pure_instructions
+
+
+define void @normal() nounwind readnone {
+; CHECK: .section __TEXT,__text,regular,pure_instructions
+; CHECK: _normal:
+ ret void
+}
+
+define void @special() nounwind readnone section "__TEXT,myprecious" {
+; CHECK: .section __TEXT,myprecious
+; CHECK: _special:
+ ret void
+}
diff --git a/test/CodeGen/ARM/deps-fix.ll b/test/CodeGen/ARM/deps-fix.ll
new file mode 100644
index 0000000000..288697a4dc
--- /dev/null
+++ b/test/CodeGen/ARM/deps-fix.ll
@@ -0,0 +1,22 @@
+; RUN: llc < %s -march=arm -mcpu=cortex-a9 -mattr=+neon,+neonfp -float-abi=hard -mtriple armv7-linux-gnueabi | FileCheck %s
+
+;; This test checks that the ExecutionDepsFix pass performs the domain changes
+;; even when some dependencies are propagated through implicit definitions.
+
+; CHECK: fun_a
+define <4 x float> @fun_a(<4 x float> %in, <4 x float> %x, float %y) nounwind {
+; CHECK: vext
+; CHECK: vext
+; CHECK: vadd.f32
+ %1 = insertelement <4 x float> %in, float %y, i32 0
+ %2 = fadd <4 x float> %1, %x
+ ret <4 x float> %2
+}
+; CHECK: fun_b
+define <4 x i32> @fun_b(<4 x i32> %in, <4 x i32> %x, i32 %y) nounwind {
+; CHECK: vmov.32
+; CHECK: vadd.i32
+ %1 = insertelement <4 x i32> %in, i32 %y, i32 0
+ %2 = add <4 x i32> %1, %x
+ ret <4 x i32> %2
+}
diff --git a/test/CodeGen/CellSPU/icmp16.ll b/test/CodeGen/CellSPU/icmp16.ll
index 2f9b091fae..853ae1db16 100644
--- a/test/CodeGen/CellSPU/icmp16.ll
+++ b/test/CodeGen/CellSPU/icmp16.ll
@@ -534,7 +534,7 @@ entry:
define i16 @icmp_slt_immed04_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_slt_immed04_i16:
; CHECK: lr
-; CHECK-NETX: bi
+; CHECK-NEXT: bi
entry:
%A = icmp slt i16 %arg1, 32768
@@ -559,7 +559,7 @@ define i1 @icmp_sle_setcc_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwi
; CHECK: ilhu
; CHECK: xorhi
; CHECK: iohl
-; CHECK-NETX: bi
+; CHECK: bi
entry:
%A = icmp sle i16 %arg1, %arg2
diff --git a/test/CodeGen/Mips/mul.ll b/test/CodeGen/Mips/mul.ll
new file mode 100644
index 0000000000..4ce801b1c9
--- /dev/null
+++ b/test/CodeGen/Mips/mul.ll
@@ -0,0 +1,17 @@
+; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16
+
+@iiii = global i32 5, align 4
+@jjjj = global i32 -6, align 4
+@kkkk = common global i32 0, align 4
+
+define void @test() nounwind {
+entry:
+ %0 = load i32* @iiii, align 4
+ %1 = load i32* @jjjj, align 4
+ %mul = mul nsw i32 %1, %0
+; 16: mult ${{[0-9]+}}, ${{[0-9]+}}
+; 16: mflo ${{[0-9]+}}
+
+ store i32 %mul, i32* @kkkk, align 4
+ ret void
+}
diff --git a/test/CodeGen/Mips/mulll.ll b/test/CodeGen/Mips/mulll.ll
new file mode 100644
index 0000000000..e37b9197df
--- /dev/null
+++ b/test/CodeGen/Mips/mulll.ll
@@ -0,0 +1,21 @@
+; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16
+
+@iiii = global i64 5, align 8
+@jjjj = global i64 -6, align 8
+@kkkk = common global i64 0, align 8
+
+define void @test() nounwind {
+entry:
+ %0 = load i64* @iiii, align 8
+ %1 = load i64* @jjjj, align 8
+ %mul = mul nsw i64 %1, %0
+ store i64 %mul, i64* @kkkk, align 8
+; 16: multu ${{[0-9]+}}, ${{[0-9]+}}
+; 16: mfhi ${{[0-9]+}}
+; 16: mult ${{[0-9]+}}, ${{[0-9]+}}
+; 16: mflo ${{[0-9]+}}
+; 16: mult ${{[0-9]+}}, ${{[0-9]+}}
+; 16: mflo ${{[0-9]+}}
+
+ ret void
+}
diff --git a/test/CodeGen/Mips/mulull.ll b/test/CodeGen/Mips/mulull.ll
new file mode 100644
index 0000000000..4d23c69318
--- /dev/null
+++ b/test/CodeGen/Mips/mulull.ll
@@ -0,0 +1,21 @@
+; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16
+
+@iiii = global i64 5, align 8
+@jjjj = global i64 6, align 8
+@kkkk = common global i64 0, align 8
+@.str = private unnamed_addr constant [20 x i8] c"%lld * %lld = %lld\0A\00", align 1
+
+define void @test() nounwind {
+entry:
+ %0 = load i64* @iiii, align 8
+ %1 = load i64* @jjjj, align 8
+ %mul = mul nsw i64 %1, %0
+ store i64 %mul, i64* @kkkk, align 8
+; 16: multu ${{[0-9]+}}, ${{[0-9]+}}
+; 16: mfhi ${{[0-9]+}}
+; 16: mult ${{[0-9]+}}, ${{[0-9]+}}
+; 16: mflo ${{[0-9]+}}
+; 16: mult ${{[0-9]+}}, ${{[0-9]+}}
+; 16: mflo ${{[0-9]+}}
+ ret void
+}
diff --git a/test/CodeGen/Mips/stldst.ll b/test/CodeGen/Mips/stldst.ll
new file mode 100644
index 0000000000..4182b9e76d
--- /dev/null
+++ b/test/CodeGen/Mips/stldst.ll
@@ -0,0 +1,41 @@
+; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16
+
+@kkkk = global i32 67, align 4
+@llll = global i32 33, align 4
+@mmmm = global i32 44, align 4
+@nnnn = global i32 55, align 4
+@oooo = global i32 32, align 4
+@pppp = global i32 41, align 4
+@qqqq = global i32 59, align 4
+@rrrr = global i32 60, align 4
+@.str = private unnamed_addr constant [32 x i8] c"%i %i %i %i %i %i %i %i %i %i \0A\00", align 1
+
+define i32 @main() nounwind {
+entry:
+ %0 = load i32* @kkkk, align 4
+ %1 = load i32* @llll, align 4
+ %add = add nsw i32 %0, 10
+ %add1 = add nsw i32 %1, 10
+ %2 = load i32* @mmmm, align 4
+ %sub = add nsw i32 %2, -3
+ %3 = load i32* @nnnn, align 4
+ %add2 = add nsw i32 %3, 10
+ %4 = load i32* @oooo, align 4
+ %add3 = add nsw i32 %4, 4
+ %5 = load i32* @pppp, align 4
+ %sub4 = add nsw i32 %5, -5
+ %6 = load i32* @qqqq, align 4
+ %sub5 = add nsw i32 %6, -10
+ %7 = load i32* @rrrr, align 4
+ %add6 = add nsw i32 %7, 6
+
+ %call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([32 x i8]* @.str, i32 0, i32 0), i32 %sub5, i32 %add6, i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, i32 %7) nounwind
+ %call7 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([32 x i8]* @.str, i32 0, i32 0), i32 %0, i32 %1, i32 %add, i32 %add1, i32 %sub, i32 %add2, i32 %add3, i32 %sub4, i32 %sub5, i32 %add6) nounwind
+ ret i32 0
+}
+; 16: sw ${{[0-9]+}}, {{[0-9]+}} ( $sp ); # 4-byte Folded Spill
+; 16: lw ${{[0-9]+}}, {{[0-9]+}} ( $sp ); # 4-byte Folded Reload
+; 16: sw ${{[0-9]+}}, {{[0-9]+}} ( $sp ); # 4-byte Folded Spill
+; 16: lw ${{[0-9]+}}, {{[0-9]+}} ( $sp ); # 4-byte Folded Reload
+
+declare i32 @printf(i8* nocapture, ...) nounwind
diff --git a/test/CodeGen/PowerPC/ppc64-toc.ll b/test/CodeGen/PowerPC/ppc64-toc.ll
index b992ab1ad3..a29bdcb250 100644
--- a/test/CodeGen/PowerPC/ppc64-toc.ll
+++ b/test/CodeGen/PowerPC/ppc64-toc.ll
@@ -1,68 +1,68 @@
-; RUN: llc < %s | FileCheck %s
-target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"
-target triple = "powerpc64-unknown-linux-gnu"
-
-@double_array = global [32 x double] zeroinitializer, align 8
-@number64 = global i64 10, align 8
-@internal_static_var.x = internal unnamed_addr global i64 0, align 8
-
-define i64 @access_int64(i64 %a) nounwind readonly {
-entry:
-; CHECK: access_int64:
-; CHECK-NEXT: .align 3
-; CHECK-NEXT: .quad .L.access_int64
-; CHECK-NEXT: .quad .TOC.@tocbase
-; CHECK-NEXT: .quad 0
-; CHECK-NEXT: .text
- %0 = load i64* @number64, align 8
-; CHECK: ld {{[0-9]+}}, .LC{{[0-9]+}}@toc(2)
- %cmp = icmp eq i64 %0, %a
- %conv1 = zext i1 %cmp to i64
- ret i64 %conv1
-}
-
-define i64 @internal_static_var(i64 %a) nounwind {
-entry:
-; CHECK: internal_static_var:
-; CHECK: ld {{[0-9]+}}, .LC{{[0-9]+}}@toc(2)
- %0 = load i64* @internal_static_var.x, align 8
- %cmp = icmp eq i64 %0, %a
- %conv1 = zext i1 %cmp to i64
- ret i64 %conv1
-}
-
-define i32 @access_double(double %a) nounwind readnone {
-entry:
-; CHECK: access_double:
-; CHECK: ld {{[0-9]+}}, .LC{{[0-9]+}}@toc(2)
- %cmp = fcmp oeq double %a, 2.000000e+00
- %conv = zext i1 %cmp to i32
- ret i32 %conv
-}
-
-
-define i32 @access_double_array(double %a, i32 %i) nounwind readonly {
-entry:
-; CHECK: access_double_array:
- %idxprom = sext i32 %i to i64
- %arrayidx = getelementptr inbounds [32 x double]* @double_array, i64 0, i64 %idxprom
- %0 = load double* %arrayidx, align 8
-; CHECK: ld {{[0-9]+}}, .LC{{[0-9]+}}@toc(2)
- %cmp = fcmp oeq double %0, %a
- %conv = zext i1 %cmp to i32
- ret i32 %conv
-}
-
-; Check the creation of 4 .tc entries:
-; * int64_t global 'number64'
-; * double constant 2.0
-; * double array 'double_array'
-; * static int64_t 'x' accessed within '@internal_static_var'
-; CHECK: .LC{{[0-9]+}}:
-; CHECK-NEXT: .tc {{[\._a-zA-Z0-9]+}}[TC],{{[\._a-zA-Z0-9]+}}
-; CHECK-NEXT: .LC{{[0-9]+}}:
-; CHECK-NEXT: .tc {{[\._a-zA-Z0-9]+}}[TC],{{[\._a-zA-Z0-9]+}}
-; CHECK-NEXT: .LC{{[0-9]+}}:
-; CHECK-NEXT: .tc {{[\._a-zA-Z0-9]+}}[TC],{{[\._a-zA-Z0-9]+}}
-; CHECK-NEXT: .LC{{[0-9]+}}:
-; CHECK-NEXT: .tc {{[\._a-zA-Z0-9]+}}[TC],{{[\._a-zA-Z0-9]+}}
+; RUN: llc < %s | FileCheck %s
+target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"
+target triple = "powerpc64-unknown-linux-gnu"
+
+@double_array = global [32 x double] zeroinitializer, align 8
+@number64 = global i64 10, align 8
+@internal_static_var.x = internal unnamed_addr global i64 0, align 8
+
+define i64 @access_int64(i64 %a) nounwind readonly {
+entry:
+; CHECK: access_int64:
+; CHECK-NEXT: .align 3
+; CHECK-NEXT: .quad .L.access_int64
+; CHECK-NEXT: .quad .TOC.@tocbase
+; CHECK-NEXT: .quad 0
+; CHECK-NEXT: .text
+ %0 = load i64* @number64, align 8
+; CHECK: ld {{[0-9]+}}, .LC{{[0-9]+}}@toc(2)
+ %cmp = icmp eq i64 %0, %a
+ %conv1 = zext i1 %cmp to i64
+ ret i64 %conv1
+}
+
+define i64 @internal_static_var(i64 %a) nounwind {
+entry:
+; CHECK: internal_static_var:
+; CHECK: ld {{[0-9]+}}, .LC{{[0-9]+}}@toc(2)
+ %0 = load i64* @internal_static_var.x, align 8
+ %cmp = icmp eq i64 %0, %a
+ %conv1 = zext i1 %cmp to i64
+ ret i64 %conv1
+}
+
+define i32 @access_double(double %a) nounwind readnone {
+entry:
+; CHECK: access_double:
+; CHECK: ld {{[0-9]+}}, .LC{{[0-9]+}}@toc(2)
+ %cmp = fcmp oeq double %a, 2.000000e+00
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+}
+
+
+define i32 @access_double_array(double %a, i32 %i) nounwind readonly {
+entry:
+; CHECK: access_double_array:
+ %idxprom = sext i32 %i to i64
+ %arrayidx = getelementptr inbounds [32 x double]* @double_array, i64 0, i64 %idxprom
+ %0 = load double* %arrayidx, align 8
+; CHECK: ld {{[0-9]+}}, .LC{{[0-9]+}}@toc(2)
+ %cmp = fcmp oeq double %0, %a
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+}
+
+; Check the creation of 4 .tc entries:
+; * int64_t global 'number64'
+; * double constant 2.0
+; * double array 'double_array'
+; * static int64_t 'x' accessed within '@internal_static_var'
+; CHECK: .LC{{[0-9]+}}:
+; CHECK-NEXT: .tc {{[\._a-zA-Z0-9]+}}[TC],{{[\._a-zA-Z0-9]+}}
+; CHECK-NEXT: .LC{{[0-9]+}}:
+; CHECK-NEXT: .tc {{[\._a-zA-Z0-9]+}}[TC],{{[\._a-zA-Z0-9]+}}
+; CHECK-NEXT: .LC{{[0-9]+}}:
+; CHECK-NEXT: .tc {{[\._a-zA-Z0-9]+}}[TC],{{[\._a-zA-Z0-9]+}}
+; CHECK-NEXT: .LC{{[0-9]+}}:
+; CHECK-NEXT: .tc {{[\._a-zA-Z0-9]+}}[TC],{{[\._a-zA-Z0-9]+}}
diff --git a/test/CodeGen/PowerPC/vec_cmp.ll b/test/CodeGen/PowerPC/vec_cmp.ll
new file mode 100644
index 0000000000..b2b59db8f1
--- /dev/null
+++ b/test/CodeGen/PowerPC/vec_cmp.ll
@@ -0,0 +1,191 @@
+; RUN: llc -mattr=+altivec < %s | FileCheck %s
+
+; Check vector comparisons using altivec.
+
+
+target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"
+target triple = "powerpc64-unknown-linux-gnu"
+
+define <2 x i8> @v2si8_cmp(<2 x i8> %x, <2 x i8> %y) nounwind readnone {
+ %cmp = icmp eq <2 x i8> %x, %y
+ %sext = sext <2 x i1> %cmp to <2 x i8>
+ ret <2 x i8> %sext
+}
+; CHECK: v2si8_cmp:
+; CHECK: vcmpequb {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+
+
+define <4 x i8> @v4si8_cmp(<4 x i8> %x, <4 x i8> %y) nounwind readnone {
+ %cmp = icmp eq <4 x i8> %x, %y
+ %sext = sext <4 x i1> %cmp to <4 x i8>
+ ret <4 x i8> %sext
+}
+; CHECK: v4si8_cmp:
+; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+
+
+define <8 x i8> @v8si8_cmp(<8 x i8> %x, <8 x i8> %y) nounwind readnone {
+ %cmp = icmp eq <8 x i8> %x, %y
+ %sext = sext <8 x i1> %cmp to <8 x i8>
+ ret <8 x i8> %sext
+}
+; CHECK: v8si8_cmp:
+; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+
+
+define <16 x i8> @v16si8_cmp(<16 x i8> %x, <16 x i8> %y) nounwind readnone {
+ %cmp = icmp eq <16 x i8> %x, %y
+ %sext = sext <16 x i1> %cmp to <16 x i8>
+ ret <16 x i8> %sext
+}
+; CHECK: v16si8_cmp:
+; CHECK: vcmpequb {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+
+
+define <32 x i8> @v32si8_cmp(<32 x i8> %x, <32 x i8> %y) nounwind readnone {
+ %cmp = icmp eq <32 x i8> %x, %y
+ %sext = sext <32 x i1> %cmp to <32 x i8>
+ ret <32 x i8> %sext
+}
+; CHECK: v32si8_cmp:
+; CHECK: vcmpequb {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: vcmpequb {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+
+
+define <2 x i16> @v2si16_cmp(<2 x i16> %x, <2 x i16> %y) nounwind readnone {
+ %cmp = icmp eq <2 x i16> %x, %y
+ %sext = sext <2 x i1> %cmp to <2 x i16>
+ ret <2 x i16> %sext
+}
+; CHECK: v2si16_cmp:
+; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+
+
+define <4 x i16> @v4si16_cmp(<4 x i16> %x, <4 x i16> %y) nounwind readnone {
+ %cmp = icmp eq <4 x i16> %x, %y
+ %sext = sext <4 x i1> %cmp to <4 x i16>
+ ret <4 x i16> %sext
+}
+; CHECK: v4si16_cmp:
+; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+
+
+define <8 x i16> @v8si16_cmp(<8 x i16> %x, <8 x i16> %y) nounwind readnone {
+ %cmp = icmp eq <8 x i16> %x, %y
+ %sext = sext <8 x i1> %cmp to <8 x i16>
+ ret <8 x i16> %sext
+}
+; CHECK: v8si16_cmp:
+; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+
+
+define <16 x i16> @v16si16_cmp(<16 x i16> %x, <16 x i16> %y) nounwind readnone {
+ %cmp = icmp eq <16 x i16> %x, %y
+ %sext = sext <16 x i1> %cmp to <16 x i16>
+ ret <16 x i16> %sext
+}
+; CHECK: v16si16_cmp:
+; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+
+
+define <32 x i16> @v32si16_cmp(<32 x i16> %x, <32 x i16> %y) nounwind readnone {
+ %cmp = icmp eq <32 x i16> %x, %y
+ %sext = sext <32 x i1> %cmp to <32 x i16>
+ ret <32 x i16> %sext
+}
+; CHECK: v32si16_cmp:
+; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: vcmpequh {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+
+
+define <2 x i32> @v2si32_cmp(<2 x i32> %x, <2 x i32> %y) nounwind readnone {
+ %cmp = icmp eq <2 x i32> %x, %y
+ %sext = sext <2 x i1> %cmp to <2 x i32>
+ ret <2 x i32> %sext
+}
+; CHECK: v2si32_cmp:
+; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+
+
+define <4 x i32> @v4si32_cmp(<4 x i32> %x, <4 x i32> %y) nounwind readnone {
+ %cmp = icmp eq <4 x i32> %x, %y
+ %sext = sext <4 x i1> %cmp to <4 x i32>
+ ret <4 x i32> %sext
+}
+; CHECK: v4si32_cmp:
+; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+
+
+define <8 x i32> @v8si32_cmp(<8 x i32> %x, <8 x i32> %y) nounwind readnone {
+ %cmp = icmp eq <8 x i32> %x, %y
+ %sext = sext <8 x i1> %cmp to <8 x i32>
+ ret <8 x i32> %sext
+}
+; CHECK: v8si32_cmp:
+; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+
+
+define <16 x i32> @v16si32_cmp(<16 x i32> %x, <16 x i32> %y) nounwind readnone {
+ %cmp = icmp eq <16 x i32> %x, %y
+ %sext = sext <16 x i1> %cmp to <16 x i32>
+ ret <16 x i32> %sext
+}
+; CHECK: v16si32_cmp:
+; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+
+
+define <32 x i32> @v32si32_cmp(<32 x i32> %x, <32 x i32> %y) nounwind readnone {
+ %cmp = icmp eq <32 x i32> %x, %y
+ %sext = sext <32 x i1> %cmp to <32 x i32>
+ ret <32 x i32> %sext
+}
+; CHECK: v32si32_cmp:
+; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: vcmpequw {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+
+
+define <2 x float> @v2f32_cmp(<2 x float> %x, <2 x float> %y) nounwind readnone {
+entry:
+ %cmp = fcmp oeq <2 x float> %x, %y
+ %sext = sext <2 x i1> %cmp to <2 x i32>
+ %0 = bitcast <2 x i32> %sext to <2 x float>
+ ret <2 x float> %0
+}
+; CHECK: v2f32_cmp:
+; CHECK: vcmpeqfp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+
+
+define <4 x float> @v4f32_cmp(<4 x float> %x, <4 x float> %y) nounwind readnone {
+entry:
+ %cmp = fcmp oeq <4 x float> %x, %y
+ %sext = sext <4 x i1> %cmp to <4 x i32>
+ %0 = bitcast <4 x i32> %sext to <4 x float>
+ ret <4 x float> %0
+}
+; CHECK: v4f32_cmp:
+; CHECK: vcmpeqfp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+
+
+define <8 x float> @v8f32_cmp(<8 x float> %x, <8 x float> %y) nounwind readnone {
+entry:
+ %cmp = fcmp oeq <8 x float> %x, %y
+ %sext = sext <8 x i1> %cmp to <8 x i32>
+ %0 = bitcast <8 x i32> %sext to <8 x float>
+ ret <8 x float> %0
+}
+; CHECK: v8f32_cmp:
+; CHECK: vcmpeqfp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
+; CHECK: vcmpeqfp {{[0-9]+}}, {{[0-9]+}}, {{[0-9]+}}
diff --git a/test/CodeGen/PowerPC/vec_conv.ll b/test/CodeGen/PowerPC/vec_conv.ll
new file mode 100644
index 0000000000..a475e9499d
--- /dev/null
+++ b/test/CodeGen/PowerPC/vec_conv.ll
@@ -0,0 +1,57 @@
+; RUN: llc -mattr=+altivec < %s | FileCheck %s
+
+; Check vector float/int conversion using altivec.
+
+target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"
+target triple = "powerpc64-unknown-linux-gnu"
+
+@cte_float = global <4 x float> <float 6.5e+00, float 6.5e+00, float 6.5e+00, float 6.5e+00>, align 16
+@cte_int = global <4 x i32> <i32 6, i32 6, i32 6, i32 6>, align 16
+
+
+define void @v4f32_to_v4i32(<4 x float> %x, <4 x i32>* nocapture %y) nounwind {
+entry:
+ %0 = load <4 x float>* @cte_float, align 16
+ %mul = fmul <4 x float> %0, %x
+ %1 = fptosi <4 x float> %mul to <4 x i32>
+ store <4 x i32> %1, <4 x i32>* %y, align 16
+ ret void
+}
+;CHECK: v4f32_to_v4i32:
+;CHECK: vctsxs {{[0-9]+}}, {{[0-9]+}}, 0
+
+
+define void @v4f32_to_v4u32(<4 x float> %x, <4 x i32>* nocapture %y) nounwind {
+entry:
+ %0 = load <4 x float>* @cte_float, align 16
+ %mul = fmul <4 x float> %0, %x
+ %1 = fptoui <4 x float> %mul to <4 x i32>
+ store <4 x i32> %1, <4 x i32>* %y, align 16
+ ret void
+}
+;CHECK: v4f32_to_v4u32:
+;CHECK: vctuxs {{[0-9]+}}, {{[0-9]+}}, 0
+
+
+define void @v4i32_to_v4f32(<4 x i32> %x, <4 x float>* nocapture %y) nounwind {
+entry:
+ %0 = load <4 x i32>* @cte_int, align 16
+ %mul = mul <4 x i32> %0, %x
+ %1 = sitofp <4 x i32> %mul to <4 x float>
+ store <4 x float> %1, <4 x float>* %y, align 16
+ ret void
+}
+;CHECK: v4i32_to_v4f32:
+;CHECK: vcfsx {{[0-9]+}}, {{[0-9]+}}, 0
+
+
+define void @v4u32_to_v4f32(<4 x i32> %x, <4 x float>* nocapture %y) nounwind {
+entry:
+ %0 = load <4 x i32>* @cte_int, align 16
+ %mul = mul <4 x i32> %0, %x
+ %1 = uitofp <4 x i32> %mul to <4 x float>
+ store <4 x float> %1, <4 x float>* %y, align 16
+ ret void
+}
+;CHECK: v4u32_to_v4f32:
+;CHECK: vcfux {{[0-9]+}}, {{[0-9]+}}, 0
diff --git a/test/CodeGen/SPARC/2011-01-11-CC.ll b/test/CodeGen/SPARC/2011-01-11-CC.ll
index 3ceda958de..f676fd8369 100755
--- a/test/CodeGen/SPARC/2011-01-11-CC.ll
+++ b/test/CodeGen/SPARC/2011-01-11-CC.ll
@@ -54,7 +54,7 @@ entry:
; V8: {{be|bne}}
; V9: test_select_dfp_icc
; V9: subcc
-; V9=NOT: {{be|bne}}
+; V9-NOT: {{be|bne}}
; V9: fmovd{{e|ne}} %icc
%0 = icmp eq i32 %a, 0
%1 = select i1 %0, double %f1, double %f2
diff --git a/test/CodeGen/X86/2012-10-02-DAGCycle.ll b/test/CodeGen/X86/2012-10-02-DAGCycle.ll
new file mode 100644
index 0000000000..8d914db331
--- /dev/null
+++ b/test/CodeGen/X86/2012-10-02-DAGCycle.ll
@@ -0,0 +1,52 @@
+; RUN: llc -mtriple=i386-apple-macosx -relocation-model=pic < %s
+; RUN: llc -mtriple=x86_64-apple-macosx -relocation-model=pic < %s
+
+; rdar://12393897
+
+%TRp = type { i32, %TRH*, i32, i32 }
+%TRH = type { i8*, i8*, i8*, i8*, {}* }
+
+define i32 @t(%TRp* inreg %rp) nounwind optsize ssp {
+entry:
+ %handler = getelementptr inbounds %TRp* %rp, i32 0, i32 1
+ %0 = load %TRH** %handler, align 4
+ %sync = getelementptr inbounds %TRH* %0, i32 0, i32 4
+ %sync12 = load {}** %sync, align 4
+ %1 = bitcast {}* %sync12 to i32 (%TRp*)*
+ %call = tail call i32 %1(%TRp* inreg %rp) nounwind optsize
+ ret i32 %call
+}
+
+%btConeShape = type { %btConvexInternalShape, float, float, float, [3 x i32] }
+%btConvexInternalShape = type { %btConvexShape, %btVector, %btVector, float, float }
+%btConvexShape = type { %btCollisionShape }
+%btCollisionShape = type { i32 (...)**, i32, i8* }
+%btVector = type { [4 x float] }
+
+define { <2 x float>, <2 x float> } @t2(%btConeShape* %this) unnamed_addr uwtable ssp align 2 {
+entry:
+ %0 = getelementptr inbounds %btConeShape* %this, i64 0, i32 0
+ br i1 undef, label %if.then, label %if.end17
+
+if.then: ; preds = %entry
+ %vecnorm.sroa.2.8.copyload = load float* undef, align 4
+ %cmp4 = fcmp olt float undef, 0x3D10000000000000
+ %vecnorm.sroa.2.8.copyload36 = select i1 %cmp4, float -1.000000e+00, float %vecnorm.sroa.2.8.copyload
+ %call.i.i.i = tail call float @sqrtf(float 0.000000e+00) nounwind readnone
+ %div.i.i = fdiv float 1.000000e+00, %call.i.i.i
+ %mul7.i.i.i = fmul float %div.i.i, %vecnorm.sroa.2.8.copyload36
+ %1 = load float (%btConvexInternalShape*)** undef, align 8
+ %call12 = tail call float %1(%btConvexInternalShape* %0)
+ %mul7.i.i = fmul float %call12, %mul7.i.i.i
+ %retval.sroa.0.4.insert = insertelement <2 x float> zeroinitializer, float undef, i32 1
+ %add13.i = fadd float undef, %mul7.i.i
+ %retval.sroa.1.8.insert = insertelement <2 x float> undef, float %add13.i, i32 0
+ br label %if.end17
+
+if.end17: ; preds = %if.then, %entry
+ %retval.sroa.1.8.load3338 = phi <2 x float> [ %retval.sroa.1.8.insert, %if.then ], [ undef, %entry ]
+ %retval.sroa.0.0.load3137 = phi <2 x float> [ %retval.sroa.0.4.insert, %if.then ], [ undef, %entry ]
+ ret { <2 x float>, <2 x float> } undef
+}
+
+declare float @sqrtf(float) nounwind readnone
diff --git a/test/CodeGen/X86/2012-10-03-DAGCycle.ll b/test/CodeGen/X86/2012-10-03-DAGCycle.ll
new file mode 100644
index 0000000000..72083c7115
--- /dev/null
+++ b/test/CodeGen/X86/2012-10-03-DAGCycle.ll
@@ -0,0 +1,31 @@
+; RUN: llc -mtriple=x86_64-apple-macosx -mcpu=corei7 < %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.8.0"
+
+%struct.pluto.0 = type { %struct.bar.1, %struct.hoge.368* }
+%struct.bar.1 = type { %i8* }
+%i8 = type { i8 }
+%struct.hoge.368 = type { i32, i32 }
+%struct.widget.375 = type { i32, i32, %i8*, %struct.hoge.368* }
+
+define fastcc void @bar(%struct.pluto.0* %arg) nounwind uwtable ssp align 2 {
+bb:
+ %tmp1 = alloca %struct.widget.375, align 8
+ %tmp2 = getelementptr inbounds %struct.pluto.0* %arg, i64 0, i32 1
+ %tmp3 = load %struct.hoge.368** %tmp2, align 8
+ store %struct.pluto.0* %arg, %struct.pluto.0** undef, align 8
+ %tmp = getelementptr inbounds %struct.widget.375* %tmp1, i64 0, i32 2
+ %tmp4 = getelementptr %struct.pluto.0* %arg, i64 0, i32 0, i32 0
+ %tmp5 = load %i8** %tmp4, align 8
+ store %i8* %tmp5, %i8** %tmp, align 8
+ %tmp6 = getelementptr inbounds %struct.widget.375* %tmp1, i64 0, i32 3
+ store %struct.hoge.368* %tmp3, %struct.hoge.368** %tmp6, align 8
+ br i1 undef, label %bb8, label %bb7
+
+bb7: ; preds = %bb
+ unreachable
+
+bb8: ; preds = %bb
+ unreachable
+}
diff --git a/test/CodeGen/X86/MergeConsecutiveStores.ll b/test/CodeGen/X86/MergeConsecutiveStores.ll
new file mode 100644
index 0000000000..64825bac97
--- /dev/null
+++ b/test/CodeGen/X86/MergeConsecutiveStores.ll
@@ -0,0 +1,305 @@
+; RUN: llc -march=x86-64 -mcpu=corei7 -mattr=+avx < %s | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.8.0"
+
+%struct.A = type { i8, i8, i8, i8, i8, i8, i8, i8 }
+%struct.B = type { i32, i32, i32, i32, i32, i32, i32, i32 }
+
+; CHECK: merge_const_store
+; save 1,2,3 ... as one big integer.
+; CHECK: movabsq $578437695752307201
+; CHECK: ret
+define void @merge_const_store(i32 %count, %struct.A* nocapture %p) nounwind uwtable noinline ssp {
+ %1 = icmp sgt i32 %count, 0
+ br i1 %1, label %.lr.ph, label %._crit_edge
+.lr.ph:
+ %i.02 = phi i32 [ %10, %.lr.ph ], [ 0, %0 ]
+ %.01 = phi %struct.A* [ %11, %.lr.ph ], [ %p, %0 ]
+ %2 = getelementptr inbounds %struct.A* %.01, i64 0, i32 0
+ store i8 1, i8* %2, align 1
+ %3 = getelementptr inbounds %struct.A* %.01, i64 0, i32 1
+ store i8 2, i8* %3, align 1
+ %4 = getelementptr inbounds %struct.A* %.01, i64 0, i32 2
+ store i8 3, i8* %4, align 1
+ %5 = getelementptr inbounds %struct.A* %.01, i64 0, i32 3
+ store i8 4, i8* %5, align 1
+ %6 = getelementptr inbounds %struct.A* %.01, i64 0, i32 4
+ store i8 5, i8* %6, align 1
+ %7 = getelementptr inbounds %struct.A* %.01, i64 0, i32 5
+ store i8 6, i8* %7, align 1
+ %8 = getelementptr inbounds %struct.A* %.01, i64 0, i32 6
+ store i8 7, i8* %8, align 1
+ %9 = getelementptr inbounds %struct.A* %.01, i64 0, i32 7
+ store i8 8, i8* %9, align 1
+ %10 = add nsw i32 %i.02, 1
+ %11 = getelementptr inbounds %struct.A* %.01, i64 1
+ %exitcond = icmp eq i32 %10, %count
+ br i1 %exitcond, label %._crit_edge, label %.lr.ph
+._crit_edge:
+ ret void
+}
+
+; Move the constants using a single vector store.
+; CHECK: merge_const_store_vec
+; CHECK: vmovups %ymm0, (%rsi)
+; CHECK: ret
+define void @merge_const_store_vec(i32 %count, %struct.B* nocapture %p) nounwind uwtable noinline ssp {
+ %1 = icmp sgt i32 %count, 0
+ br i1 %1, label %.lr.ph, label %._crit_edge
+.lr.ph:
+ %i.02 = phi i32 [ %10, %.lr.ph ], [ 0, %0 ]
+ %.01 = phi %struct.B* [ %11, %.lr.ph ], [ %p, %0 ]
+ %2 = getelementptr inbounds %struct.B* %.01, i64 0, i32 0
+ store i32 0, i32* %2, align 4
+ %3 = getelementptr inbounds %struct.B* %.01, i64 0, i32 1
+ store i32 0, i32* %3, align 4
+ %4 = getelementptr inbounds %struct.B* %.01, i64 0, i32 2
+ store i32 0, i32* %4, align 4
+ %5 = getelementptr inbounds %struct.B* %.01, i64 0, i32 3
+ store i32 0, i32* %5, align 4
+ %6 = getelementptr inbounds %struct.B* %.01, i64 0, i32 4
+ store i32 0, i32* %6, align 4
+ %7 = getelementptr inbounds %struct.B* %.01, i64 0, i32 5
+ store i32 0, i32* %7, align 4
+ %8 = getelementptr inbounds %struct.B* %.01, i64 0, i32 6
+ store i32 0, i32* %8, align 4
+ %9 = getelementptr inbounds %struct.B* %.01, i64 0, i32 7
+ store i32 0, i32* %9, align 4
+ %10 = add nsw i32 %i.02, 1
+ %11 = getelementptr inbounds %struct.B* %.01, i64 1
+ %exitcond = icmp eq i32 %10, %count
+ br i1 %exitcond, label %._crit_edge, label %.lr.ph
+._crit_edge:
+ ret void
+}
+
+; Move the first 4 constants as a single vector. Move the rest as scalars.
+; CHECK: merge_nonconst_store
+; CHECK: movl $67305985
+; CHECK: movb
+; CHECK: movb
+; CHECK: movb
+; CHECK: movb
+; CHECK: ret
+define void @merge_nonconst_store(i32 %count, i8 %zz, %struct.A* nocapture %p) nounwind uwtable noinline ssp {
+ %1 = icmp sgt i32 %count, 0
+ br i1 %1, label %.lr.ph, label %._crit_edge
+.lr.ph:
+ %i.02 = phi i32 [ %10, %.lr.ph ], [ 0, %0 ]
+ %.01 = phi %struct.A* [ %11, %.lr.ph ], [ %p, %0 ]
+ %2 = getelementptr inbounds %struct.A* %.01, i64 0, i32 0
+ store i8 1, i8* %2, align 1
+ %3 = getelementptr inbounds %struct.A* %.01, i64 0, i32 1
+ store i8 2, i8* %3, align 1
+ %4 = getelementptr inbounds %struct.A* %.01, i64 0, i32 2
+ store i8 3, i8* %4, align 1
+ %5 = getelementptr inbounds %struct.A* %.01, i64 0, i32 3
+ store i8 4, i8* %5, align 1
+ %6 = getelementptr inbounds %struct.A* %.01, i64 0, i32 4
+ store i8 %zz, i8* %6, align 1 ; <----------- Not a const;
+ %7 = getelementptr inbounds %struct.A* %.01, i64 0, i32 5
+ store i8 6, i8* %7, align 1
+ %8 = getelementptr inbounds %struct.A* %.01, i64 0, i32 6
+ store i8 7, i8* %8, align 1
+ %9 = getelementptr inbounds %struct.A* %.01, i64 0, i32 7
+ store i8 8, i8* %9, align 1
+ %10 = add nsw i32 %i.02, 1
+ %11 = getelementptr inbounds %struct.A* %.01, i64 1
+ %exitcond = icmp eq i32 %10, %count
+ br i1 %exitcond, label %._crit_edge, label %.lr.ph
+._crit_edge:
+ ret void
+}
+
+
+;CHECK: merge_loads_i16
+; load:
+;CHECK: movw
+; store:
+;CHECK: movw
+;CHECK: ret
+define void @merge_loads_i16(i32 %count, %struct.A* noalias nocapture %q, %struct.A* noalias nocapture %p) nounwind uwtable noinline ssp {
+ %1 = icmp sgt i32 %count, 0
+ br i1 %1, label %.lr.ph, label %._crit_edge
+
+.lr.ph: ; preds = %0
+ %2 = getelementptr inbounds %struct.A* %q, i64 0, i32 0
+ %3 = getelementptr inbounds %struct.A* %q, i64 0, i32 1
+ br label %4
+
+; <label>:4 ; preds = %4, %.lr.ph
+ %i.02 = phi i32 [ 0, %.lr.ph ], [ %9, %4 ]
+ %.01 = phi %struct.A* [ %p, %.lr.ph ], [ %10, %4 ]
+ %5 = load i8* %2, align 1
+ %6 = load i8* %3, align 1
+ %7 = getelementptr inbounds %struct.A* %.01, i64 0, i32 0
+ store i8 %5, i8* %7, align 1
+ %8 = getelementptr inbounds %struct.A* %.01, i64 0, i32 1
+ store i8 %6, i8* %8, align 1
+ %9 = add nsw i32 %i.02, 1
+ %10 = getelementptr inbounds %struct.A* %.01, i64 1
+ %exitcond = icmp eq i32 %9, %count
+ br i1 %exitcond, label %._crit_edge, label %4
+
+._crit_edge: ; preds = %4, %0
+ ret void
+}
+
+; The loads and the stores are interleved. Can't merge them.
+;CHECK: no_merge_loads
+;CHECK: movb
+;CHECK: movb
+;CHECK: movb
+;CHECK: movb
+;CHECK: ret
+define void @no_merge_loads(i32 %count, %struct.A* noalias nocapture %q, %struct.A* noalias nocapture %p) nounwind uwtable noinline ssp {
+ %1 = icmp sgt i32 %count, 0
+ br i1 %1, label %.lr.ph, label %._crit_edge
+
+.lr.ph: ; preds = %0
+ %2 = getelementptr inbounds %struct.A* %q, i64 0, i32 0
+ %3 = getelementptr inbounds %struct.A* %q, i64 0, i32 1
+ br label %a4
+
+a4: ; preds = %4, %.lr.ph
+ %i.02 = phi i32 [ 0, %.lr.ph ], [ %a9, %a4 ]
+ %.01 = phi %struct.A* [ %p, %.lr.ph ], [ %a10, %a4 ]
+ %a5 = load i8* %2, align 1
+ %a7 = getelementptr inbounds %struct.A* %.01, i64 0, i32 0
+ store i8 %a5, i8* %a7, align 1
+ %a8 = getelementptr inbounds %struct.A* %.01, i64 0, i32 1
+ %a6 = load i8* %3, align 1
+ store i8 %a6, i8* %a8, align 1
+ %a9 = add nsw i32 %i.02, 1
+ %a10 = getelementptr inbounds %struct.A* %.01, i64 1
+ %exitcond = icmp eq i32 %a9, %count
+ br i1 %exitcond, label %._crit_edge, label %a4
+
+._crit_edge: ; preds = %4, %0
+ ret void
+}
+
+
+;CHECK: merge_loads_integer
+; load:
+;CHECK: movq
+; store:
+;CHECK: movq
+;CHECK: ret
+define void @merge_loads_integer(i32 %count, %struct.B* noalias nocapture %q, %struct.B* noalias nocapture %p) nounwind uwtable noinline ssp {
+ %1 = icmp sgt i32 %count, 0
+ br i1 %1, label %.lr.ph, label %._crit_edge
+
+.lr.ph: ; preds = %0
+ %2 = getelementptr inbounds %struct.B* %q, i64 0, i32 0
+ %3 = getelementptr inbounds %struct.B* %q, i64 0, i32 1
+ br label %4
+
+; <label>:4 ; preds = %4, %.lr.ph
+ %i.02 = phi i32 [ 0, %.lr.ph ], [ %9, %4 ]
+ %.01 = phi %struct.B* [ %p, %.lr.ph ], [ %10, %4 ]
+ %5 = load i32* %2
+ %6 = load i32* %3
+ %7 = getelementptr inbounds %struct.B* %.01, i64 0, i32 0
+ store i32 %5, i32* %7
+ %8 = getelementptr inbounds %struct.B* %.01, i64 0, i32 1
+ store i32 %6, i32* %8
+ %9 = add nsw i32 %i.02, 1
+ %10 = getelementptr inbounds %struct.B* %.01, i64 1
+ %exitcond = icmp eq i32 %9, %count
+ br i1 %exitcond, label %._crit_edge, label %4
+
+._crit_edge: ; preds = %4, %0
+ ret void
+}
+
+
+;CHECK: merge_loads_vector
+; load:
+;CHECK: movups
+; store:
+;CHECK: movups
+;CHECK: ret
+define void @merge_loads_vector(i32 %count, %struct.B* noalias nocapture %q, %struct.B* noalias nocapture %p) nounwind uwtable noinline ssp {
+ %a1 = icmp sgt i32 %count, 0
+ br i1 %a1, label %.lr.ph, label %._crit_edge
+
+.lr.ph: ; preds = %0
+ %a2 = getelementptr inbounds %struct.B* %q, i64 0, i32 0
+ %a3 = getelementptr inbounds %struct.B* %q, i64 0, i32 1
+ %a4 = getelementptr inbounds %struct.B* %q, i64 0, i32 2
+ %a5 = getelementptr inbounds %struct.B* %q, i64 0, i32 3
+ br label %block4
+
+block4: ; preds = %4, %.lr.ph
+ %i.02 = phi i32 [ 0, %.lr.ph ], [ %c9, %block4 ]
+ %.01 = phi %struct.B* [ %p, %.lr.ph ], [ %c10, %block4 ]
+ %a7 = getelementptr inbounds %struct.B* %.01, i64 0, i32 0
+ %a8 = getelementptr inbounds %struct.B* %.01, i64 0, i32 1
+ %a9 = getelementptr inbounds %struct.B* %.01, i64 0, i32 2
+ %a10 = getelementptr inbounds %struct.B* %.01, i64 0, i32 3
+ %b1 = load i32* %a2
+ %b2 = load i32* %a3
+ %b3 = load i32* %a4
+ %b4 = load i32* %a5
+ store i32 %b1, i32* %a7
+ store i32 %b2, i32* %a8
+ store i32 %b3, i32* %a9
+ store i32 %b4, i32* %a10
+ %c9 = add nsw i32 %i.02, 1
+ %c10 = getelementptr inbounds %struct.B* %.01, i64 1
+ %exitcond = icmp eq i32 %c9, %count
+ br i1 %exitcond, label %._crit_edge, label %block4
+
+._crit_edge: ; preds = %4, %0
+ ret void
+}
+
+;CHECK: merge_loads_no_align
+; load:
+;CHECK: movl
+;CHECK: movl
+;CHECK: movl
+;CHECK: movl
+; store:
+;CHECK: movl
+;CHECK: movl
+;CHECK: movl
+;CHECK: movl
+;CHECK: ret
+define void @merge_loads_no_align(i32 %count, %struct.B* noalias nocapture %q, %struct.B* noalias nocapture %p) nounwind uwtable noinline ssp {
+ %a1 = icmp sgt i32 %count, 0
+ br i1 %a1, label %.lr.ph, label %._crit_edge
+
+.lr.ph: ; preds = %0
+ %a2 = getelementptr inbounds %struct.B* %q, i64 0, i32 0
+ %a3 = getelementptr inbounds %struct.B* %q, i64 0, i32 1
+ %a4 = getelementptr inbounds %struct.B* %q, i64 0, i32 2
+ %a5 = getelementptr inbounds %struct.B* %q, i64 0, i32 3
+ br label %block4
+
+block4: ; preds = %4, %.lr.ph
+ %i.02 = phi i32 [ 0, %.lr.ph ], [ %c9, %block4 ]
+ %.01 = phi %struct.B* [ %p, %.lr.ph ], [ %c10, %block4 ]
+ %a7 = getelementptr inbounds %struct.B* %.01, i64 0, i32 0
+ %a8 = getelementptr inbounds %struct.B* %.01, i64 0, i32 1
+ %a9 = getelementptr inbounds %struct.B* %.01, i64 0, i32 2
+ %a10 = getelementptr inbounds %struct.B* %.01, i64 0, i32 3
+ %b1 = load i32* %a2, align 1
+ %b2 = load i32* %a3, align 1
+ %b3 = load i32* %a4, align 1
+ %b4 = load i32* %a5, align 1
+ store i32 %b1, i32* %a7, align 1
+ store i32 %b2, i32* %a8, align 1
+ store i32 %b3, i32* %a9, align 1
+ store i32 %b4, i32* %a10, align 1
+ %c9 = add nsw i32 %i.02, 1
+ %c10 = getelementptr inbounds %struct.B* %.01, i64 1
+ %exitcond = icmp eq i32 %c9, %count
+ br i1 %exitcond, label %._crit_edge, label %block4
+
+._crit_edge: ; preds = %4, %0
+ ret void
+}
+
diff --git a/test/CodeGen/X86/cmov-fp.ll b/test/CodeGen/X86/cmov-fp.ll
new file mode 100644
index 0000000000..ca91f9ea2c
--- /dev/null
+++ b/test/CodeGen/X86/cmov-fp.ll
@@ -0,0 +1,451 @@
+; RUN: llc -march x86 -mcpu pentium4 < %s | FileCheck %s -check-prefix=SSE
+; RUN: llc -march x86 -mcpu pentium3 < %s | FileCheck %s -check-prefix=NOSSE2
+; RUN: llc -march x86 -mcpu pentium2 < %s | FileCheck %s -check-prefix=NOSSE1
+; RUN: llc -march x86 -mcpu pentium < %s | FileCheck %s -check-prefix=NOCMOV
+; PR14035
+
+define double @test1(i32 %a, i32 %b, double %x) nounwind {
+ %cmp = icmp ugt i32 %a, %b
+ %sel = select i1 %cmp, double 99.0, double %x
+ ret double %sel
+
+; SSE: test1:
+; SSE: movsd
+
+; NOSSE2: test1:
+; NOSSE2: fcmovnbe
+
+; NOSSE1: test1:
+; NOSSE1: fcmovnbe
+
+; NOCMOV: test1:
+; NOCMOV: fstp
+
+}
+
+define double @test2(i32 %a, i32 %b, double %x) nounwind {
+ %cmp = icmp uge i32 %a, %b
+ %sel = select i1 %cmp, double 99.0, double %x
+ ret double %sel
+
+; SSE: test2:
+; SSE: movsd
+
+; NOSSE2: test2:
+; NOSSE2: fcmovnb
+
+; NOSSE1: test2:
+; NOSSE1: fcmovnb
+
+; NOCMOV: test2:
+; NOCMOV: fstp
+}
+
+define double @test3(i32 %a, i32 %b, double %x) nounwind {
+ %cmp = icmp ult i32 %a, %b
+ %sel = select i1 %cmp, double 99.0, double %x
+ ret double %sel
+
+; SSE: test3:
+; SSE: movsd
+
+; NOSSE2: test3:
+; NOSSE2: fcmovb
+
+; NOSSE1: test3:
+; NOSSE1: fcmovb
+
+; NOCMOV: test3:
+; NOCMOV: fstp
+}
+
+define double @test4(i32 %a, i32 %b, double %x) nounwind {
+ %cmp = icmp ule i32 %a, %b
+ %sel = select i1 %cmp, double 99.0, double %x
+ ret double %sel
+
+; SSE: test4:
+; SSE: movsd
+
+; NOSSE2: test4:
+; NOSSE2: fcmovbe
+
+; NOSSE1: test4:
+; NOSSE1: fcmovbe
+
+; NOCMOV: test4:
+; NOCMOV: fstp
+}
+
+define double @test5(i32 %a, i32 %b, double %x) nounwind {
+ %cmp = icmp sgt i32 %a, %b
+ %sel = select i1 %cmp, double 99.0, double %x
+ ret double %sel
+
+; SSE: test5:
+; SSE: movsd
+
+; NOSSE2: test5:
+; NOSSE2: fstp
+
+; NOSSE1: test5:
+; NOSSE1: fstp
+
+; NOCMOV: test5:
+; NOCMOV: fstp
+}
+
+define double @test6(i32 %a, i32 %b, double %x) nounwind {
+ %cmp = icmp sge i32 %a, %b
+ %sel = select i1 %cmp, double 99.0, double %x
+ ret double %sel
+
+; SSE: test6:
+; SSE: movsd
+
+; NOSSE2: test6:
+; NOSSE2: fstp
+
+; NOSSE1: test6:
+; NOSSE1: fstp
+
+; NOCMOV: test6:
+; NOCMOV: fstp
+}
+
+define double @test7(i32 %a, i32 %b, double %x) nounwind {
+ %cmp = icmp slt i32 %a, %b
+ %sel = select i1 %cmp, double 99.0, double %x
+ ret double %sel
+
+; SSE: test7:
+; SSE: movsd
+
+; NOSSE2: test7:
+; NOSSE2: fstp
+
+; NOSSE1: test7:
+; NOSSE1: fstp
+
+; NOCMOV: test7:
+; NOCMOV: fstp
+}
+
+define double @test8(i32 %a, i32 %b, double %x) nounwind {
+ %cmp = icmp sle i32 %a, %b
+ %sel = select i1 %cmp, double 99.0, double %x
+ ret double %sel
+
+; SSE: test8:
+; SSE: movsd
+
+; NOSSE2: test8:
+; NOSSE2: fstp
+
+; NOSSE1: test8:
+; NOSSE1: fstp
+
+; NOCMOV: test8:
+; NOCMOV: fstp
+}
+
+define float @test9(i32 %a, i32 %b, float %x) nounwind {
+ %cmp = icmp ugt i32 %a, %b
+ %sel = select i1 %cmp, float 99.0, float %x
+ ret float %sel
+
+; SSE: test9:
+; SSE: movss
+
+; NOSSE2: test9:
+; NOSSE2: movss
+
+; NOSSE1: test9:
+; NOSSE1: fcmovnbe
+
+; NOCMOV: test9:
+; NOCMOV: fstp
+}
+
+define float @test10(i32 %a, i32 %b, float %x) nounwind {
+ %cmp = icmp uge i32 %a, %b
+ %sel = select i1 %cmp, float 99.0, float %x
+ ret float %sel
+
+; SSE: test10:
+; SSE: movss
+
+; NOSSE2: test10:
+; NOSSE2: movss
+
+; NOSSE1: test10:
+; NOSSE1: fcmovnb
+
+; NOCMOV: test10:
+; NOCMOV: fstp
+}
+
+define float @test11(i32 %a, i32 %b, float %x) nounwind {
+ %cmp = icmp ult i32 %a, %b
+ %sel = select i1 %cmp, float 99.0, float %x
+ ret float %sel
+
+; SSE: test11:
+; SSE: movss
+
+; NOSSE2: test11:
+; NOSSE2: movss
+
+; NOSSE1: test11:
+; NOSSE1: fcmovb
+
+; NOCMOV: test11:
+; NOCMOV: fstp
+}
+
+define float @test12(i32 %a, i32 %b, float %x) nounwind {
+ %cmp = icmp ule i32 %a, %b
+ %sel = select i1 %cmp, float 99.0, float %x
+ ret float %sel
+
+; SSE: test12:
+; SSE: movss
+
+; NOSSE2: test12:
+; NOSSE2: movss
+
+; NOSSE1: test12:
+; NOSSE1: fcmovbe
+
+; NOCMOV: test12:
+; NOCMOV: fstp
+}
+
+define float @test13(i32 %a, i32 %b, float %x) nounwind {
+ %cmp = icmp sgt i32 %a, %b
+ %sel = select i1 %cmp, float 99.0, float %x
+ ret float %sel
+
+; SSE: test13:
+; SSE: movss
+
+; NOSSE2: test13:
+; NOSSE2: movss
+
+; NOSSE1: test13:
+; NOSSE1: fstp
+
+; NOCMOV: test13:
+; NOCMOV: fstp
+}
+
+define float @test14(i32 %a, i32 %b, float %x) nounwind {
+ %cmp = icmp sge i32 %a, %b
+ %sel = select i1 %cmp, float 99.0, float %x
+ ret float %sel
+
+; SSE: test14:
+; SSE: movss
+
+; NOSSE2: test14:
+; NOSSE2: movss
+
+; NOSSE1: test14:
+; NOSSE1: fstp
+
+; NOCMOV: test14:
+; NOCMOV: fstp
+}
+
+define float @test15(i32 %a, i32 %b, float %x) nounwind {
+ %cmp = icmp slt i32 %a, %b
+ %sel = select i1 %cmp, float 99.0, float %x
+ ret float %sel
+
+; SSE: test15:
+; SSE: movss
+
+; NOSSE2: test15:
+; NOSSE2: movss
+
+; NOSSE1: test15:
+; NOSSE1: fstp
+
+; NOCMOV: test15:
+; NOCMOV: fstp
+}
+
+define float @test16(i32 %a, i32 %b, float %x) nounwind {
+ %cmp = icmp sle i32 %a, %b
+ %sel = select i1 %cmp, float 99.0, float %x
+ ret float %sel
+
+; SSE: test16:
+; SSE: movss
+
+; NOSSE2: test16:
+; NOSSE2: movss
+
+; NOSSE1: test16:
+; NOSSE1: fstp
+
+; NOCMOV: test16:
+; NOCMOV: fstp
+}
+
+define x86_fp80 @test17(i32 %a, i32 %b, x86_fp80 %x) nounwind {
+ %cmp = icmp ugt i32 %a, %b
+ %sel = select i1 %cmp, x86_fp80 0xK4005C600000000000000, x86_fp80 %x
+ ret x86_fp80 %sel
+
+; SSE: test17:
+; SSE: fcmovnbe
+
+; NOSSE2: test17:
+; NOSSE2: fcmovnbe
+
+; NOSSE1: test17:
+; NOSSE1: fcmovnbe
+
+; NOCMOV: test17:
+; NOCMOV: fstp
+}
+
+define x86_fp80 @test18(i32 %a, i32 %b, x86_fp80 %x) nounwind {
+ %cmp = icmp uge i32 %a, %b
+ %sel = select i1 %cmp, x86_fp80 0xK4005C600000000000000, x86_fp80 %x
+ ret x86_fp80 %sel
+
+; SSE: test18:
+; SSE: fcmovnb
+
+; NOSSE2: test18:
+; NOSSE2: fcmovnb
+
+; NOSSE1: test18:
+; NOSSE1: fcmovnb
+
+; NOCMOV: test18:
+; NOCMOV: fstp
+}
+
+define x86_fp80 @test19(i32 %a, i32 %b, x86_fp80 %x) nounwind {
+ %cmp = icmp ult i32 %a, %b
+ %sel = select i1 %cmp, x86_fp80 0xK4005C600000000000000, x86_fp80 %x
+ ret x86_fp80 %sel
+
+; SSE: test19:
+; SSE: fcmovb
+
+; NOSSE2: test19:
+; NOSSE2: fcmovb
+
+; NOSSE1: test19:
+; NOSSE1: fcmovb
+
+; NOCMOV: test19:
+; NOCMOV: fstp
+}
+
+define x86_fp80 @test20(i32 %a, i32 %b, x86_fp80 %x) nounwind {
+ %cmp = icmp ule i32 %a, %b
+ %sel = select i1 %cmp, x86_fp80 0xK4005C600000000000000, x86_fp80 %x
+ ret x86_fp80 %sel
+
+; SSE: test20:
+; SSE: fcmovbe
+
+; NOSSE2: test20:
+; NOSSE2: fcmovbe
+
+; NOSSE1: test20:
+; NOSSE1: fcmovbe
+
+; NOCMOV: test20:
+; NOCMOV: fstp
+}
+
+define x86_fp80 @test21(i32 %a, i32 %b, x86_fp80 %x) nounwind {
+ %cmp = icmp sgt i32 %a, %b
+ %sel = select i1 %cmp, x86_fp80 0xK4005C600000000000000, x86_fp80 %x
+ ret x86_fp80 %sel
+
+; We don't emit a branch for fp80, why?
+; SSE: test21:
+; SSE: testb
+; SSE: fcmovne
+
+; NOSSE2: test21:
+; NOSSE2: testb
+; NOSSE2: fcmovne
+
+; NOSSE1: test21:
+; NOSSE1: testb
+; NOSSE1: fcmovne
+
+; NOCMOV: test21:
+; NOCMOV: fstp
+}
+
+define x86_fp80 @test22(i32 %a, i32 %b, x86_fp80 %x) nounwind {
+ %cmp = icmp sge i32 %a, %b
+ %sel = select i1 %cmp, x86_fp80 0xK4005C600000000000000, x86_fp80 %x
+ ret x86_fp80 %sel
+
+; SSE: test22:
+; SSE: testb
+; SSE: fcmovne
+
+; NOSSE2: test22:
+; NOSSE2: testb
+; NOSSE2: fcmovne
+
+; NOSSE1: test22:
+; NOSSE1: testb
+; NOSSE1: fcmovne
+
+; NOCMOV: test22:
+; NOCMOV: fstp
+}
+
+define x86_fp80 @test23(i32 %a, i32 %b, x86_fp80 %x) nounwind {
+ %cmp = icmp slt i32 %a, %b
+ %sel = select i1 %cmp, x86_fp80 0xK4005C600000000000000, x86_fp80 %x
+ ret x86_fp80 %sel
+
+; SSE: test23:
+; SSE: testb
+; SSE: fcmovne
+
+; NOSSE2: test23:
+; NOSSE2: testb
+; NOSSE2: fcmovne
+
+; NOSSE1: test23:
+; NOSSE1: testb
+; NOSSE1: fcmovne
+
+; NOCMOV: test23:
+; NOCMOV: fstp
+}
+
+define x86_fp80 @test24(i32 %a, i32 %b, x86_fp80 %x) nounwind {
+ %cmp = icmp sle i32 %a, %b
+ %sel = select i1 %cmp, x86_fp80 0xK4005C600000000000000, x86_fp80 %x
+ ret x86_fp80 %sel
+
+; SSE: test24:
+; SSE: testb
+; SSE: fcmovne
+
+; NOSSE2: test24:
+; NOSSE2: testb
+; NOSSE2: fcmovne
+
+; NOSSE1: test24:
+; NOSSE1: testb
+; NOSSE1: fcmovne
+
+; NOCMOV: test24:
+; NOCMOV: fstp
+}
diff --git a/test/CodeGen/X86/early-ifcvt.ll b/test/CodeGen/X86/early-ifcvt.ll
index 7883ffabd5..2e1852d3e3 100644
--- a/test/CodeGen/X86/early-ifcvt.ll
+++ b/test/CodeGen/X86/early-ifcvt.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -enable-early-ifcvt -stress-early-ifcvt | FileCheck %s
+; RUN: llc < %s -x86-early-ifcvt -stress-early-ifcvt | FileCheck %s
target triple = "x86_64-apple-macosx10.8.0"
; CHECK: mm2
@@ -67,3 +67,78 @@ if.end41:
}
declare void @fprintf(...) nounwind
+
+; CHECK: BZ2_decompress
+; This test case contains irreducible control flow, so MachineLoopInfo doesn't
+; recognize the cycle in the CFG. This would confuse MachineTraceMetrics.
+define void @BZ2_decompress(i8* %s) nounwind ssp {
+entry:
+ switch i32 undef, label %sw.default [
+ i32 39, label %if.end.sw.bb2050_crit_edge
+ i32 36, label %sw.bb1788
+ i32 37, label %if.end.sw.bb1855_crit_edge
+ i32 40, label %sw.bb2409
+ i32 38, label %sw.bb1983
+ i32 44, label %if.end.sw.bb3058_crit_edge
+ ]
+
+if.end.sw.bb3058_crit_edge: ; preds = %entry
+ br label %save_state_and_return
+
+if.end.sw.bb1855_crit_edge: ; preds = %entry
+ br label %save_state_and_return
+
+if.end.sw.bb2050_crit_edge: ; preds = %entry
+ br label %sw.bb2050
+
+sw.bb1788: ; preds = %entry
+ br label %save_state_and_return
+
+sw.bb1983: ; preds = %entry
+ br i1 undef, label %save_state_and_return, label %if.then1990
+
+if.then1990: ; preds = %sw.bb1983
+ br label %while.body2038
+
+while.body2038: ; preds = %sw.bb2050, %if.then1990
+ %groupPos.8 = phi i32 [ 0, %if.then1990 ], [ %groupPos.9, %sw.bb2050 ]
+ br i1 undef, label %save_state_and_return, label %if.end2042
+
+if.end2042: ; preds = %while.body2038
+ br i1 undef, label %if.end2048, label %while.end2104
+
+if.end2048: ; preds = %if.end2042
+ %bsLive2054.pre = getelementptr inbounds i8* %s, i32 8
+ br label %sw.bb2050
+
+sw.bb2050: ; preds = %if.end2048, %if.end.sw.bb2050_crit_edge
+ %groupPos.9 = phi i32 [ 0, %if.end.sw.bb2050_crit_edge ], [ %groupPos.8, %if.end2048 ]
+ %and2064 = and i32 undef, 1
+ br label %while.body2038
+
+while.end2104: ; preds = %if.end2042
+ br i1 undef, label %save_state_and_return, label %if.end2117
+
+if.end2117: ; preds = %while.end2104
+ br i1 undef, label %while.body2161.lr.ph, label %while.body2145.lr.ph
+
+while.body2145.lr.ph: ; preds = %if.end2117
+ br label %save_state_and_return
+
+while.body2161.lr.ph: ; preds = %if.end2117
+ br label %save_state_and_return
+
+sw.bb2409: ; preds = %entry
+ br label %save_state_and_return
+
+sw.default: ; preds = %entry
+ call void @BZ2_bz__AssertH__fail() nounwind
+ br label %save_state_and_return
+
+save_state_and_return:
+ %groupPos.14 = phi i32 [ 0, %sw.default ], [ %groupPos.8, %while.body2038 ], [ %groupPos.8, %while.end2104 ], [ 0, %if.end.sw.bb3058_crit_edge ], [ 0, %if.end.sw.bb1855_crit_edge ], [ %groupPos.8, %while.body2161.lr.ph ], [ %groupPos.8, %while.body2145.lr.ph ], [ 0, %sw.bb2409 ], [ 0, %sw.bb1788 ], [ 0, %sw.bb1983 ]
+ store i32 %groupPos.14, i32* undef, align 4
+ ret void
+}
+
+declare void @BZ2_bz__AssertH__fail()
diff --git a/test/CodeGen/X86/fast-isel-x86-64.ll b/test/CodeGen/X86/fast-isel-x86-64.ll
index 85a70aad75..cdfaf7f4c1 100644
--- a/test/CodeGen/X86/fast-isel-x86-64.ll
+++ b/test/CodeGen/X86/fast-isel-x86-64.ll
@@ -291,3 +291,16 @@ entry:
}
declare void @foo22(i32)
+
+; PR13563
+define void @test23(i8* noalias sret %result) {
+ %a = alloca i8
+ %b = call i8* @foo23()
+ ret void
+; CHECK: test23:
+; CHECK: call
+; CHECK: movq %rdi, %rax
+; CHECK: ret
+}
+
+declare i8* @foo23()
diff --git a/test/CodeGen/X86/ms-inline-asm.ll b/test/CodeGen/X86/ms-inline-asm.ll
index cd06fe68a6..59efa8d547 100644
--- a/test/CodeGen/X86/ms-inline-asm.ll
+++ b/test/CodeGen/X86/ms-inline-asm.ll
@@ -24,3 +24,17 @@ entry:
; CHECK: .att_syntax
; CHECK: {{## InlineAsm End|#NO_APP}}
}
+
+define void @t3(i32 %V) nounwind {
+entry:
+ %V.addr = alloca i32, align 4
+ store i32 %V, i32* %V.addr, align 4
+ call void asm sideeffect inteldialect "mov eax, DWORD PTR [$0]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %V.addr) nounwind
+ ret void
+; CHECK: t3
+; CHECK: {{## InlineAsm Start|#APP}}
+; CHECK: .intel_syntax
+; CHECK: mov eax, DWORD PTR {{[[esp]}}
+; CHECK: .att_syntax
+; CHECK: {{## InlineAsm End|#NO_APP}}
+}
diff --git a/test/CodeGen/X86/pr13899.ll b/test/CodeGen/X86/pr13899.ll
new file mode 100644
index 0000000000..bc81e34d67
--- /dev/null
+++ b/test/CodeGen/X86/pr13899.ll
@@ -0,0 +1,58 @@
+; RUN: llc < %s -mtriple=i386-pc-win32 -mcpu=corei7 | FileCheck %s
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=core-avx2 | FileCheck %s --check-prefix=X64
+
+; ModuleID = 'a.bc'
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32"
+target triple = "i386-pc-win32"
+
+%v4_varying_big_struct = type { [4 x <4 x i32>] }
+
+declare <4 x i32> @"foo"(%v4_varying_big_struct, <4 x i32>) nounwind
+
+define <4 x i32> @"bar"(%v4_varying_big_struct %s, <4 x i32> %__mask) nounwind {
+allocas:
+ %calltmp = call <4 x i32> @"foo"(%v4_varying_big_struct %s, <4 x i32> %__mask)
+ ret <4 x i32> %calltmp
+; CHECK: bar
+; CHECK: andl
+; CHECK: call
+; CHECK: ret
+}
+
+declare <8 x float> @bar64(<8 x float> %i0, <8 x float> %i1,
+ <8 x float> %i2, <8 x float> %i3,
+ <8 x float> %i4, <8 x float> %i5,
+ <8 x float> %i6, <8 x float> %i7,
+ <8 x float> %i8, <8 x float> %i9)
+
+define <8 x float> @foo64(<8 x float>* %p) {
+ %1 = load <8 x float>* %p
+ %idx1 = getelementptr inbounds <8 x float>* %p, i64 1
+ %2 = load <8 x float>* %idx1
+ %idx2 = getelementptr inbounds <8 x float>* %p, i64 2
+ %3 = load <8 x float>* %idx2
+ %idx3 = getelementptr inbounds <8 x float>* %p, i64 3
+ %4 = load <8 x float>* %idx3
+ %idx4 = getelementptr inbounds <8 x float>* %p, i64 4
+ %5 = load <8 x float>* %idx4
+ %idx5 = getelementptr inbounds <8 x float>* %p, i64 5
+ %6 = load <8 x float>* %idx5
+ %idx6 = getelementptr inbounds <8 x float>* %p, i64 6
+ %7 = load <8 x float>* %idx6
+ %idx7 = getelementptr inbounds <8 x float>* %p, i64 7
+ %8 = load <8 x float>* %idx7
+ %idx8 = getelementptr inbounds <8 x float>* %p, i64 8
+ %9 = load <8 x float>* %idx8
+ %idx9 = getelementptr inbounds <8 x float>* %p, i64 9
+ %10 = load <8 x float>* %idx9
+ %r = tail call <8 x float> @bar64(<8 x float> %1, <8 x float> %2,
+ <8 x float> %3, <8 x float> %4,
+ <8 x float> %5, <8 x float> %6,
+ <8 x float> %7, <8 x float> %8,
+ <8 x float> %9, <8 x float> %10)
+ ret <8 x float> %r
+; X64: foo
+; X64: and
+; X64: call
+; X64: ret
+}
diff --git a/test/CodeGen/X86/red-zone2.ll b/test/CodeGen/X86/red-zone2.ll
index f09216319e..3e9c7909a3 100644
--- a/test/CodeGen/X86/red-zone2.ll
+++ b/test/CodeGen/X86/red-zone2.ll
@@ -1,6 +1,7 @@
-; RUN: llc < %s -mcpu=generic -march=x86-64 > %t
-; RUN: grep subq %t | count 1
-; RUN: grep addq %t | count 1
+; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux | FileCheck %s
+; CHECK: f0:
+; CHECK: subq
+; CHECK: addq
define x86_fp80 @f0(float %f) nounwind readnone noredzone {
entry:
diff --git a/test/CodeGen/X86/smul-with-overflow.ll b/test/CodeGen/X86/smul-with-overflow.ll
index 7ac3840482..2d0b2f7aa9 100644
--- a/test/CodeGen/X86/smul-with-overflow.ll
+++ b/test/CodeGen/X86/smul-with-overflow.ll
@@ -67,3 +67,17 @@ entry:
; CHECK: mull
; CHECK-NEXT: ret
}
+
+declare { i63, i1 } @llvm.smul.with.overflow.i63(i63, i63) nounwind readnone
+
+define i1 @test5() nounwind {
+entry:
+ %res = call { i63, i1 } @llvm.smul.with.overflow.i63(i63 4, i63 4611686018427387903)
+ %sum = extractvalue { i63, i1 } %res, 0
+ %overflow = extractvalue { i63, i1 } %res, 1
+ ret i1 %overflow
+; Was returning false, should return true (not constant folded yet though).
+; PR13991
+; CHECK: test5:
+; CHECK-NOT: xorb
+}
diff --git a/test/DebugInfo/X86/DW_AT_byte_size.ll b/test/DebugInfo/X86/DW_AT_byte_size.ll
index 59280e027f..25b5f00c6a 100644
--- a/test/DebugInfo/X86/DW_AT_byte_size.ll
+++ b/test/DebugInfo/X86/DW_AT_byte_size.ll
@@ -4,7 +4,8 @@
; Checks that we don't emit a size for a pointer type.
; CHECK: DW_TAG_pointer_type
; CHECK-NEXT: DW_AT_type
-; CHECK-NOT-NEXT: DW_AT_byte_size
+; CHECK-NOT: DW_AT_byte_size
+; CHECK: .debug_info contents
%struct.A = type { i32 }
diff --git a/test/DebugInfo/X86/enum-fwd-decl.ll b/test/DebugInfo/X86/enum-fwd-decl.ll
index c2dacea483..0902430008 100644
--- a/test/DebugInfo/X86/enum-fwd-decl.ll
+++ b/test/DebugInfo/X86/enum-fwd-decl.ll
@@ -5,16 +5,14 @@
!llvm.dbg.cu = !{!0}
-!0 = metadata !{i32 786449, i32 0, i32 4, metadata !"foo.cpp", metadata !"/Users/echristo/tmp", metadata !"clang version 3.2 (trunk 157772) (llvm/trunk 157761)", i1 true, i1 false, metadata !"", i32 0, metadata !1, metadata !6, metadata !6, metadata !7} ; [ DW_TAG_compile_unit ]
+!0 = metadata !{i32 786449, i32 0, i32 4, metadata !"foo.cpp", metadata !"/tmp", metadata !"clang version 3.2 (trunk 165274) (llvm/trunk 165272)", i1 true, i1 false, metadata !"", i32 0, metadata !1, metadata !1, metadata !1, metadata !3} ; [ DW_TAG_compile_unit ] [/tmp/foo.cpp] [DW_LANG_C_plus_plus]
!1 = metadata !{metadata !2}
-!2 = metadata !{metadata !3}
-!3 = metadata !{i32 786436, null, metadata !"E", metadata !4, i32 1, i64 16, i64 16, i32 0, i32 4, null, metadata !5, i32 0, i32 0} ; [ DW_TAG_enumeration_type ]
-!4 = metadata !{i32 786473, metadata !"foo.cpp", metadata !"/Users/echristo/tmp", null} ; [ DW_TAG_file_type ]
-!5 = metadata !{i32 0}
-!6 = metadata !{metadata !5}
-!7 = metadata !{metadata !8}
-!8 = metadata !{metadata !9}
-!9 = metadata !{i32 786484, i32 0, null, metadata !"e", metadata !"e", metadata !"", metadata !4, i32 2, metadata !3, i32 0, i32 1, i16* @e} ; [ DW_TAG_variable ]
+!2 = metadata !{i32 0}
+!3 = metadata !{metadata !4}
+!4 = metadata !{metadata !5}
+!5 = metadata !{i32 786484, i32 0, null, metadata !"e", metadata !"e", metadata !"", metadata !6, i32 2, metadata !7, i32 0, i32 1, i16* @e} ; [ DW_TAG_variable ] [e] [line 2] [def]
+!6 = metadata !{i32 786473, metadata !"foo.cpp", metadata !"/tmp", null} ; [ DW_TAG_file_type ]
+!7 = metadata !{i32 786436, null, metadata !"E", metadata !6, i32 1, i64 16, i64 16, i32 0, i32 4, null, null, i32 0} ; [ DW_TAG_enumeration_type ] [E] [line 1, size 16, align 16, offset 0] [fwd] [from ]
; CHECK: DW_TAG_enumeration_type
; CHECK-NEXT: DW_AT_name
diff --git a/test/DebugInfo/X86/prologue-stack.ll b/test/DebugInfo/X86/prologue-stack.ll
new file mode 100644
index 0000000000..929db51902
--- /dev/null
+++ b/test/DebugInfo/X86/prologue-stack.ll
@@ -0,0 +1,35 @@
+; RUN: llc -disable-fp-elim -O0 %s -mtriple x86_64-unknown-linux-gnu -o - | FileCheck %s
+
+; int callme(int);
+; int isel_line_test2() {
+; callme(400);
+; return 0;
+; }
+
+define i32 @isel_line_test2() nounwind uwtable {
+ ; The stack adjustment should be part of the prologue.
+ ; CHECK: isel_line_test2:
+ ; CHECK: {{subq|leaq}} {{.*}}, %rsp
+ ; CHECK: .loc 1 5 3 prologue_end
+entry:
+ %call = call i32 @callme(i32 400), !dbg !10
+ ret i32 0, !dbg !12
+}
+
+declare i32 @callme(i32)
+
+!llvm.dbg.cu = !{!0}
+
+!0 = metadata !{i32 786449, i32 0, i32 12, metadata !"bar.c", metadata !"/usr/local/google/home/echristo/tmp", metadata !"clang version 3.2 (trunk 164980) (llvm/trunk 164979)", i1 true, i1 false, metadata !"", i32 0, metadata !1, metadata !1, metadata !3, metadata !1} ; [ DW_TAG_compile_unit ] [/usr/local/google/home/echristo/tmp/bar.c] [DW_LANG_C99]
+!1 = metadata !{metadata !2}
+!2 = metadata !{i32 0}
+!3 = metadata !{metadata !4}
+!4 = metadata !{metadata !5}
+!5 = metadata !{i32 786478, i32 0, metadata !6, metadata !"isel_line_test2", metadata !"isel_line_test2", metadata !"", metadata !6, i32 3, metadata !7, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, i32 ()* @isel_line_test2, null, null, metadata !1, i32 4} ; [ DW_TAG_subprogram ] [line 3] [def] [scope 4] [isel_line_test2]
+!6 = metadata !{i32 786473, metadata !"bar.c", metadata !"/usr/local/google/home/echristo/tmp", null} ; [ DW_TAG_file_type ]
+!7 = metadata !{i32 786453, i32 0, metadata !"", i32 0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!8 = metadata !{metadata !9}
+!9 = metadata !{i32 786468, null, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+!10 = metadata !{i32 5, i32 3, metadata !11, null}
+!11 = metadata !{i32 786443, metadata !5, i32 4, i32 1, metadata !6, i32 0} ; [ DW_TAG_lexical_block ] [/usr/local/google/home/echristo/tmp/bar.c]
+!12 = metadata !{i32 6, i32 3, metadata !11, null}
diff --git a/test/ExecutionEngine/2002-12-16-ArgTest.ll b/test/ExecutionEngine/2002-12-16-ArgTest.ll
index eb2fe8c048..4c03519a85 100644
--- a/test/ExecutionEngine/2002-12-16-ArgTest.ll
+++ b/test/ExecutionEngine/2002-12-16-ArgTest.ll
@@ -1,4 +1,5 @@
; RUN: %lli %s > /dev/null
+; XFAIL: arm
@.LC0 = internal global [10 x i8] c"argc: %d\0A\00" ; <[10 x i8]*> [#uses=1]
diff --git a/test/ExecutionEngine/MCJIT/2002-12-16-ArgTest.ll b/test/ExecutionEngine/MCJIT/2002-12-16-ArgTest.ll
index 46273d3400..28cc54a868 100644
--- a/test/ExecutionEngine/MCJIT/2002-12-16-ArgTest.ll
+++ b/test/ExecutionEngine/MCJIT/2002-12-16-ArgTest.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
@.LC0 = internal global [10 x i8] c"argc: %d\0A\00" ; <[10 x i8]*> [#uses=1]
diff --git a/test/ExecutionEngine/MCJIT/2003-01-04-ArgumentBug.ll b/test/ExecutionEngine/MCJIT/2003-01-04-ArgumentBug.ll
index 88bfbb3c09..9f895983fd 100644
--- a/test/ExecutionEngine/MCJIT/2003-01-04-ArgumentBug.ll
+++ b/test/ExecutionEngine/MCJIT/2003-01-04-ArgumentBug.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define i32 @foo(i32 %X, i32 %Y, double %A) {
%cond212 = fcmp une double %A, 1.000000e+00 ; <i1> [#uses=1]
diff --git a/test/ExecutionEngine/MCJIT/2003-01-04-LoopTest.ll b/test/ExecutionEngine/MCJIT/2003-01-04-LoopTest.ll
index d5f860d170..997b2a9037 100644
--- a/test/ExecutionEngine/MCJIT/2003-01-04-LoopTest.ll
+++ b/test/ExecutionEngine/MCJIT/2003-01-04-LoopTest.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define i32 @main() {
call i32 @mylog( i32 4 ) ; <i32>:1 [#uses=0]
diff --git a/test/ExecutionEngine/MCJIT/2003-01-04-PhiTest.ll b/test/ExecutionEngine/MCJIT/2003-01-04-PhiTest.ll
index 721f2e8859..ba35b5bcc4 100644
--- a/test/ExecutionEngine/MCJIT/2003-01-04-PhiTest.ll
+++ b/test/ExecutionEngine/MCJIT/2003-01-04-PhiTest.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define i32 @main() {
; <label>:0
diff --git a/test/ExecutionEngine/MCJIT/2003-01-09-SARTest.ll b/test/ExecutionEngine/MCJIT/2003-01-09-SARTest.ll
index d17df997c8..f3c88adf84 100644
--- a/test/ExecutionEngine/MCJIT/2003-01-09-SARTest.ll
+++ b/test/ExecutionEngine/MCJIT/2003-01-09-SARTest.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
; We were accidentally inverting the signedness of right shifts. Whoops.
diff --git a/test/ExecutionEngine/MCJIT/2003-01-10-FUCOM.ll b/test/ExecutionEngine/MCJIT/2003-01-10-FUCOM.ll
index e55cb06aa1..f925e79f24 100644
--- a/test/ExecutionEngine/MCJIT/2003-01-10-FUCOM.ll
+++ b/test/ExecutionEngine/MCJIT/2003-01-10-FUCOM.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define i32 @main() {
%X = fadd double 0.000000e+00, 1.000000e+00 ; <double> [#uses=1]
diff --git a/test/ExecutionEngine/MCJIT/2003-01-15-AlignmentTest.ll b/test/ExecutionEngine/MCJIT/2003-01-15-AlignmentTest.ll
index 663dc40010..5b426f6c33 100644
--- a/test/ExecutionEngine/MCJIT/2003-01-15-AlignmentTest.ll
+++ b/test/ExecutionEngine/MCJIT/2003-01-15-AlignmentTest.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define i32 @bar(i8* %X) {
; pointer should be 4 byte aligned!
diff --git a/test/ExecutionEngine/MCJIT/2003-05-06-LivenessClobber.ll b/test/ExecutionEngine/MCJIT/2003-05-06-LivenessClobber.ll
index e95294be74..c0a7393f82 100644
--- a/test/ExecutionEngine/MCJIT/2003-05-06-LivenessClobber.ll
+++ b/test/ExecutionEngine/MCJIT/2003-05-06-LivenessClobber.ll
@@ -1,6 +1,6 @@
; This testcase should return with an exit code of 1.
;
-; RUN: not %lli -use-mcjit %s
+; RUN: not %lli -mtriple=%mcjit_triple -use-mcjit %s
@test = global i64 0 ; <i64*> [#uses=1]
diff --git a/test/ExecutionEngine/MCJIT/2003-05-07-ArgumentTest.ll b/test/ExecutionEngine/MCJIT/2003-05-07-ArgumentTest.ll
index a237194ea4..d3e6204a85 100644
--- a/test/ExecutionEngine/MCJIT/2003-05-07-ArgumentTest.ll
+++ b/test/ExecutionEngine/MCJIT/2003-05-07-ArgumentTest.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s test
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s test
declare i32 @puts(i8*)
diff --git a/test/ExecutionEngine/MCJIT/2003-05-11-PHIRegAllocBug.ll b/test/ExecutionEngine/MCJIT/2003-05-11-PHIRegAllocBug.ll
index 70464a3ffc..55a1697541 100644
--- a/test/ExecutionEngine/MCJIT/2003-05-11-PHIRegAllocBug.ll
+++ b/test/ExecutionEngine/MCJIT/2003-05-11-PHIRegAllocBug.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
target datalayout = "e-p:32:32"
diff --git a/test/ExecutionEngine/MCJIT/2003-06-04-bzip2-bug.ll b/test/ExecutionEngine/MCJIT/2003-06-04-bzip2-bug.ll
index 58d423f924..79c6e7fe4c 100644
--- a/test/ExecutionEngine/MCJIT/2003-06-04-bzip2-bug.ll
+++ b/test/ExecutionEngine/MCJIT/2003-06-04-bzip2-bug.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
; Testcase distilled from 256.bzip2.
diff --git a/test/ExecutionEngine/MCJIT/2003-06-05-PHIBug.ll b/test/ExecutionEngine/MCJIT/2003-06-05-PHIBug.ll
index a22fe07b08..ffd6df6e5e 100644
--- a/test/ExecutionEngine/MCJIT/2003-06-05-PHIBug.ll
+++ b/test/ExecutionEngine/MCJIT/2003-06-05-PHIBug.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
; Testcase distilled from 256.bzip2.
diff --git a/test/ExecutionEngine/MCJIT/2003-08-15-AllocaAssertion.ll b/test/ExecutionEngine/MCJIT/2003-08-15-AllocaAssertion.ll
index b3c6d8abbc..90839e9698 100644
--- a/test/ExecutionEngine/MCJIT/2003-08-15-AllocaAssertion.ll
+++ b/test/ExecutionEngine/MCJIT/2003-08-15-AllocaAssertion.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
; This testcase failed to work because two variable sized allocas confused the
; local register allocator.
diff --git a/test/ExecutionEngine/MCJIT/2003-08-21-EnvironmentTest.ll b/test/ExecutionEngine/MCJIT/2003-08-21-EnvironmentTest.ll
index bd32f3037d..29ef2c556c 100644
--- a/test/ExecutionEngine/MCJIT/2003-08-21-EnvironmentTest.ll
+++ b/test/ExecutionEngine/MCJIT/2003-08-21-EnvironmentTest.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
;
; Regression Test: EnvironmentTest.ll
diff --git a/test/ExecutionEngine/MCJIT/2003-08-23-RegisterAllocatePhysReg.ll b/test/ExecutionEngine/MCJIT/2003-08-23-RegisterAllocatePhysReg.ll
index 1959534b87..2adb608acb 100644
--- a/test/ExecutionEngine/MCJIT/2003-08-23-RegisterAllocatePhysReg.ll
+++ b/test/ExecutionEngine/MCJIT/2003-08-23-RegisterAllocatePhysReg.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
; This testcase exposes a bug in the local register allocator where it runs out
; of registers (due to too many overlapping live ranges), but then attempts to
diff --git a/test/ExecutionEngine/MCJIT/2003-10-18-PHINode-ConstantExpr-CondCode-Failure.ll b/test/ExecutionEngine/MCJIT/2003-10-18-PHINode-ConstantExpr-CondCode-Failure.ll
index 1f8343fc43..91bde46903 100644
--- a/test/ExecutionEngine/MCJIT/2003-10-18-PHINode-ConstantExpr-CondCode-Failure.ll
+++ b/test/ExecutionEngine/MCJIT/2003-10-18-PHINode-ConstantExpr-CondCode-Failure.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
@A = global i32 0 ; <i32*> [#uses=1]
diff --git a/test/ExecutionEngine/MCJIT/2005-12-02-TailCallBug.ll b/test/ExecutionEngine/MCJIT/2005-12-02-TailCallBug.ll
index 79a7d583ce..a7462d9e69 100644
--- a/test/ExecutionEngine/MCJIT/2005-12-02-TailCallBug.ll
+++ b/test/ExecutionEngine/MCJIT/2005-12-02-TailCallBug.ll
@@ -1,5 +1,5 @@
; PR672
-; RUN: %lli -use-mcjit %s
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s
; XFAIL: mcjit-ia32
define i32 @main() {
diff --git a/test/ExecutionEngine/MCJIT/2007-12-10-APIntLoadStore.ll b/test/ExecutionEngine/MCJIT/2007-12-10-APIntLoadStore.ll
index 52cef4d35c..2406596602 100644
--- a/test/ExecutionEngine/MCJIT/2007-12-10-APIntLoadStore.ll
+++ b/test/ExecutionEngine/MCJIT/2007-12-10-APIntLoadStore.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit -force-interpreter %s
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit -force-interpreter %s
; PR1836
define i32 @main() {
diff --git a/test/ExecutionEngine/MCJIT/2008-06-05-APInt-OverAShr.ll b/test/ExecutionEngine/MCJIT/2008-06-05-APInt-OverAShr.ll
index a6e917f457..d429d519e0 100644
--- a/test/ExecutionEngine/MCJIT/2008-06-05-APInt-OverAShr.ll
+++ b/test/ExecutionEngine/MCJIT/2008-06-05-APInt-OverAShr.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit -force-interpreter=true %s | grep 1
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit -force-interpreter=true %s | grep 1
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
target triple = "i686-pc-linux-gnu"
diff --git a/test/ExecutionEngine/MCJIT/2010-01-15-UndefValue.ll b/test/ExecutionEngine/MCJIT/2010-01-15-UndefValue.ll
index 524a724c47..a6d18e7919 100644
--- a/test/ExecutionEngine/MCJIT/2010-01-15-UndefValue.ll
+++ b/test/ExecutionEngine/MCJIT/2010-01-15-UndefValue.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit -force-interpreter=true %s
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit -force-interpreter=true %s > /dev/null
define i32 @main() {
%a = add i32 0, undef
diff --git a/test/ExecutionEngine/MCJIT/fpbitcast.ll b/test/ExecutionEngine/MCJIT/fpbitcast.ll
index 9da908f8cf..bb4957e9e6 100644
--- a/test/ExecutionEngine/MCJIT/fpbitcast.ll
+++ b/test/ExecutionEngine/MCJIT/fpbitcast.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit -force-interpreter=true %s | grep 40091eb8
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit -force-interpreter=true %s | grep 40091eb8
;
define i32 @test(double %x) {
entry:
diff --git a/test/ExecutionEngine/MCJIT/hello.ll b/test/ExecutionEngine/MCJIT/hello.ll
index a52b6d48af..ceb9c12ab4 100644
--- a/test/ExecutionEngine/MCJIT/hello.ll
+++ b/test/ExecutionEngine/MCJIT/hello.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
@.LC0 = internal global [12 x i8] c"Hello World\00" ; <[12 x i8]*> [#uses=1]
diff --git a/test/ExecutionEngine/MCJIT/hello2.ll b/test/ExecutionEngine/MCJIT/hello2.ll
index 670a6dd671..756fcadb1c 100644
--- a/test/ExecutionEngine/MCJIT/hello2.ll
+++ b/test/ExecutionEngine/MCJIT/hello2.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
@X = global i32 7 ; <i32*> [#uses=0]
@msg = internal global [13 x i8] c"Hello World\0A\00" ; <[13 x i8]*> [#uses=1]
diff --git a/test/ExecutionEngine/MCJIT/lit.local.cfg b/test/ExecutionEngine/MCJIT/lit.local.cfg
index 2980ce7081..af3d13f746 100644
--- a/test/ExecutionEngine/MCJIT/lit.local.cfg
+++ b/test/ExecutionEngine/MCJIT/lit.local.cfg
@@ -16,5 +16,5 @@ else:
if root.host_arch not in ['x86', 'x86_64', 'ARM', 'Mips']:
config.unsupported = True
-if root.host_os in ['Win32', 'Cygwin', 'MingW', 'Windows', 'Darwin']:
+if root.host_os in ['Darwin']:
config.unsupported = True
diff --git a/test/ExecutionEngine/MCJIT/pr13727.ll b/test/ExecutionEngine/MCJIT/pr13727.ll
index 5fa68f9b87..c33bf32810 100644
--- a/test/ExecutionEngine/MCJIT/pr13727.ll
+++ b/test/ExecutionEngine/MCJIT/pr13727.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit -O0 -disable-lazy-compilation=false %s
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit -O0 -disable-lazy-compilation=false %s
; The intention of this test is to verify that symbols mapped to COMMON in ELF
; work as expected.
diff --git a/test/ExecutionEngine/MCJIT/simplesttest.ll b/test/ExecutionEngine/MCJIT/simplesttest.ll
index a6688c237c..02ad0061fd 100644
--- a/test/ExecutionEngine/MCJIT/simplesttest.ll
+++ b/test/ExecutionEngine/MCJIT/simplesttest.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define i32 @main() {
ret i32 0
diff --git a/test/ExecutionEngine/MCJIT/simpletest.ll b/test/ExecutionEngine/MCJIT/simpletest.ll
index 4562aa6012..958b783067 100644
--- a/test/ExecutionEngine/MCJIT/simpletest.ll
+++ b/test/ExecutionEngine/MCJIT/simpletest.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define i32 @bar() {
ret i32 0
diff --git a/test/ExecutionEngine/MCJIT/stubs.ll b/test/ExecutionEngine/MCJIT/stubs.ll
index b285b0eadb..9e5d5b2e41 100644
--- a/test/ExecutionEngine/MCJIT/stubs.ll
+++ b/test/ExecutionEngine/MCJIT/stubs.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit -disable-lazy-compilation=false %s
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit -disable-lazy-compilation=false %s
define i32 @main() nounwind {
entry:
diff --git a/test/ExecutionEngine/MCJIT/test-arith.ll b/test/ExecutionEngine/MCJIT/test-arith.ll
index 31777604d5..b73227fe63 100644
--- a/test/ExecutionEngine/MCJIT/test-arith.ll
+++ b/test/ExecutionEngine/MCJIT/test-arith.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define i32 @main() {
%A = add i8 0, 12 ; <i8> [#uses=1]
diff --git a/test/ExecutionEngine/MCJIT/test-branch.ll b/test/ExecutionEngine/MCJIT/test-branch.ll
index 702c110220..8f3c727905 100644
--- a/test/ExecutionEngine/MCJIT/test-branch.ll
+++ b/test/ExecutionEngine/MCJIT/test-branch.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
; test unconditional branch
define i32 @main() {
diff --git a/test/ExecutionEngine/MCJIT/test-call-no-external-funcs.ll b/test/ExecutionEngine/MCJIT/test-call-no-external-funcs.ll
index 6f284055fd..20150b2de6 100644
--- a/test/ExecutionEngine/MCJIT/test-call-no-external-funcs.ll
+++ b/test/ExecutionEngine/MCJIT/test-call-no-external-funcs.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define i32 @_Z14func_exit_codev() nounwind uwtable {
entry:
diff --git a/test/ExecutionEngine/MCJIT/test-call.ll b/test/ExecutionEngine/MCJIT/test-call.ll
index 7a244ee505..51d19fe991 100644
--- a/test/ExecutionEngine/MCJIT/test-call.ll
+++ b/test/ExecutionEngine/MCJIT/test-call.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
declare void @exit(i32)
diff --git a/test/ExecutionEngine/MCJIT/test-cast.ll b/test/ExecutionEngine/MCJIT/test-cast.ll
index 75e7d1b423..dcc97f4665 100644
--- a/test/ExecutionEngine/MCJIT/test-cast.ll
+++ b/test/ExecutionEngine/MCJIT/test-cast.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define i32 @foo() {
ret i32 0
diff --git a/test/ExecutionEngine/MCJIT/test-common-symbols.ll b/test/ExecutionEngine/MCJIT/test-common-symbols.ll
index ac1d9acd95..8c8190291f 100644
--- a/test/ExecutionEngine/MCJIT/test-common-symbols.ll
+++ b/test/ExecutionEngine/MCJIT/test-common-symbols.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit -O0 -disable-lazy-compilation=false %s
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit -O0 -disable-lazy-compilation=false %s
; The intention of this test is to verify that symbols mapped to COMMON in ELF
; work as expected.
diff --git a/test/ExecutionEngine/MCJIT/test-constantexpr.ll b/test/ExecutionEngine/MCJIT/test-constantexpr.ll
index 6b46639c51..56c1290448 100644
--- a/test/ExecutionEngine/MCJIT/test-constantexpr.ll
+++ b/test/ExecutionEngine/MCJIT/test-constantexpr.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
; This tests to make sure that we can evaluate weird constant expressions
diff --git a/test/ExecutionEngine/MCJIT/test-fp-no-external-funcs.ll b/test/ExecutionEngine/MCJIT/test-fp-no-external-funcs.ll
index 35491df791..7af1d8b539 100644
--- a/test/ExecutionEngine/MCJIT/test-fp-no-external-funcs.ll
+++ b/test/ExecutionEngine/MCJIT/test-fp-no-external-funcs.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define double @test(double* %DP, double %Arg) {
%D = load double* %DP ; <double> [#uses=1]
diff --git a/test/ExecutionEngine/MCJIT/test-fp.ll b/test/ExecutionEngine/MCJIT/test-fp.ll
index 6fc5a501f6..f7e6fb9ba1 100644
--- a/test/ExecutionEngine/MCJIT/test-fp.ll
+++ b/test/ExecutionEngine/MCJIT/test-fp.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define double @test(double* %DP, double %Arg) {
%D = load double* %DP ; <double> [#uses=1]
diff --git a/test/ExecutionEngine/MCJIT/test-global-init-nonzero.ll b/test/ExecutionEngine/MCJIT/test-global-init-nonzero.ll
index 4a790c6ff1..ec6cbad2f1 100644
--- a/test/ExecutionEngine/MCJIT/test-global-init-nonzero.ll
+++ b/test/ExecutionEngine/MCJIT/test-global-init-nonzero.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
@count = global i32 1, align 4
diff --git a/test/ExecutionEngine/MCJIT/test-global.ll b/test/ExecutionEngine/MCJIT/test-global.ll
index 94e0250769..e7972f978e 100644
--- a/test/ExecutionEngine/MCJIT/test-global.ll
+++ b/test/ExecutionEngine/MCJIT/test-global.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
@count = global i32 0, align 4
diff --git a/test/ExecutionEngine/MCJIT/test-loadstore.ll b/test/ExecutionEngine/MCJIT/test-loadstore.ll
index e9171490e3..f450d0ab52 100644
--- a/test/ExecutionEngine/MCJIT/test-loadstore.ll
+++ b/test/ExecutionEngine/MCJIT/test-loadstore.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define void @test(i8* %P, i16* %P.upgrd.1, i32* %P.upgrd.2, i64* %P.upgrd.3) {
%V = load i8* %P ; <i8> [#uses=1]
diff --git a/test/ExecutionEngine/MCJIT/test-local.ll b/test/ExecutionEngine/MCJIT/test-local.ll
index 4f5ae47dd0..d4e9f444e4 100644
--- a/test/ExecutionEngine/MCJIT/test-local.ll
+++ b/test/ExecutionEngine/MCJIT/test-local.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define i32 @main() nounwind uwtable {
entry:
diff --git a/test/ExecutionEngine/MCJIT/test-logical.ll b/test/ExecutionEngine/MCJIT/test-logical.ll
index 0540c22fc6..32f45ef119 100644
--- a/test/ExecutionEngine/MCJIT/test-logical.ll
+++ b/test/ExecutionEngine/MCJIT/test-logical.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define i32 @main() {
%A = and i8 4, 8 ; <i8> [#uses=2]
diff --git a/test/ExecutionEngine/MCJIT/test-loop.ll b/test/ExecutionEngine/MCJIT/test-loop.ll
index b1dbf40899..ebc689664d 100644
--- a/test/ExecutionEngine/MCJIT/test-loop.ll
+++ b/test/ExecutionEngine/MCJIT/test-loop.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define i32 @main() {
; <label>:0
diff --git a/test/ExecutionEngine/MCJIT/test-phi.ll b/test/ExecutionEngine/MCJIT/test-phi.ll
index fbc080862c..1408533d7a 100644
--- a/test/ExecutionEngine/MCJIT/test-phi.ll
+++ b/test/ExecutionEngine/MCJIT/test-phi.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
; test phi node
@Y = global i32 6 ; <i32*> [#uses=1]
diff --git a/test/ExecutionEngine/MCJIT/test-ptr-reloc.ll b/test/ExecutionEngine/MCJIT/test-ptr-reloc.ll
new file mode 100644
index 0000000000..93b6a6deff
--- /dev/null
+++ b/test/ExecutionEngine/MCJIT/test-ptr-reloc.ll
@@ -0,0 +1,16 @@
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit -O0 %s
+
+@.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1
+@ptr = global i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0), align 4
+@.str1 = private unnamed_addr constant [6 x i8] c"data2\00", align 1
+@ptr2 = global i8* getelementptr inbounds ([6 x i8]* @.str1, i32 0, i32 0), align 4
+
+define i32 @main(i32 %argc, i8** nocapture %argv) nounwind readonly {
+entry:
+ %0 = load i8** @ptr, align 4
+ %1 = load i8** @ptr2, align 4
+ %cmp = icmp eq i8* %0, %1
+ %. = zext i1 %cmp to i32
+ ret i32 %.
+}
+
diff --git a/test/ExecutionEngine/MCJIT/test-ret.ll b/test/ExecutionEngine/MCJIT/test-ret.ll
index 1b90ee0750..af28292690 100644
--- a/test/ExecutionEngine/MCJIT/test-ret.ll
+++ b/test/ExecutionEngine/MCJIT/test-ret.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
; test return instructions
define void @test1() {
diff --git a/test/ExecutionEngine/MCJIT/test-return.ll b/test/ExecutionEngine/MCJIT/test-return.ll
index 9c399cab38..67f7107c3d 100644
--- a/test/ExecutionEngine/MCJIT/test-return.ll
+++ b/test/ExecutionEngine/MCJIT/test-return.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define i32 @main() nounwind uwtable {
entry:
diff --git a/test/ExecutionEngine/MCJIT/test-setcond-fp.ll b/test/ExecutionEngine/MCJIT/test-setcond-fp.ll
index 030ff31756..a8f4bd8529 100644
--- a/test/ExecutionEngine/MCJIT/test-setcond-fp.ll
+++ b/test/ExecutionEngine/MCJIT/test-setcond-fp.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define i32 @main() {
diff --git a/test/ExecutionEngine/MCJIT/test-setcond-int.ll b/test/ExecutionEngine/MCJIT/test-setcond-int.ll
index 1113efee51..ed52b5065c 100644
--- a/test/ExecutionEngine/MCJIT/test-setcond-int.ll
+++ b/test/ExecutionEngine/MCJIT/test-setcond-int.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define i32 @main() {
%int1 = add i32 0, 0 ; <i32> [#uses=6]
diff --git a/test/ExecutionEngine/MCJIT/test-shift.ll b/test/ExecutionEngine/MCJIT/test-shift.ll
index 2da824fecc..5a5c10d560 100644
--- a/test/ExecutionEngine/MCJIT/test-shift.ll
+++ b/test/ExecutionEngine/MCJIT/test-shift.ll
@@ -1,4 +1,4 @@
-; RUN: %lli -use-mcjit %s > /dev/null
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit %s > /dev/null
define i32 @main() {
%shamt = add i8 0, 1 ; <i8> [#uses=8]
diff --git a/test/ExecutionEngine/test-fp-no-external-funcs.ll b/test/ExecutionEngine/test-fp-no-external-funcs.ll
index 61b12c2abe..139b2efea5 100644
--- a/test/ExecutionEngine/test-fp-no-external-funcs.ll
+++ b/test/ExecutionEngine/test-fp-no-external-funcs.ll
@@ -1,4 +1,5 @@
; RUN: %lli %s > /dev/null
+; XFAIL: arm
define double @test(double* %DP, double %Arg) {
%D = load double* %DP ; <double> [#uses=1]
diff --git a/test/ExecutionEngine/test-fp.ll b/test/ExecutionEngine/test-fp.ll
index 2bf0210d8b..c9064500d4 100644
--- a/test/ExecutionEngine/test-fp.ll
+++ b/test/ExecutionEngine/test-fp.ll
@@ -1,4 +1,5 @@
; RUN: %lli %s > /dev/null
+; XFAIL: arm
define double @test(double* %DP, double %Arg) {
%D = load double* %DP ; <double> [#uses=1]
diff --git a/test/Instrumentation/ThreadSanitizer/atomic.ll b/test/Instrumentation/ThreadSanitizer/atomic.ll
index 02bf215c6b..ed3c821205 100644
--- a/test/Instrumentation/ThreadSanitizer/atomic.ll
+++ b/test/Instrumentation/ThreadSanitizer/atomic.ll
@@ -8,7 +8,7 @@ entry:
ret i8 %0
}
; CHECK: atomic8_load_unordered
-; CHECK: call i8 @__tsan_atomic8_load(i8* %a, i32 1)
+; CHECK: call i8 @__tsan_atomic8_load(i8* %a, i32 100501)
define i8 @atomic8_load_monotonic(i8* %a) nounwind uwtable {
entry:
@@ -16,7 +16,7 @@ entry:
ret i8 %0
}
; CHECK: atomic8_load_monotonic
-; CHECK: call i8 @__tsan_atomic8_load(i8* %a, i32 1)
+; CHECK: call i8 @__tsan_atomic8_load(i8* %a, i32 100501)
define i8 @atomic8_load_acquire(i8* %a) nounwind uwtable {
entry:
@@ -24,7 +24,7 @@ entry:
ret i8 %0
}
; CHECK: atomic8_load_acquire
-; CHECK: call i8 @__tsan_atomic8_load(i8* %a, i32 4)
+; CHECK: call i8 @__tsan_atomic8_load(i8* %a, i32 100504)
define i8 @atomic8_load_seq_cst(i8* %a) nounwind uwtable {
entry:
@@ -32,7 +32,7 @@ entry:
ret i8 %0
}
; CHECK: atomic8_load_seq_cst
-; CHECK: call i8 @__tsan_atomic8_load(i8* %a, i32 32)
+; CHECK: call i8 @__tsan_atomic8_load(i8* %a, i32 100532)
define void @atomic8_store_unordered(i8* %a) nounwind uwtable {
entry:
@@ -40,7 +40,7 @@ entry:
ret void
}
; CHECK: atomic8_store_unordered
-; CHECK: call void @__tsan_atomic8_store(i8* %a, i8 0, i32 1)
+; CHECK: call void @__tsan_atomic8_store(i8* %a, i8 0, i32 100501)
define void @atomic8_store_monotonic(i8* %a) nounwind uwtable {
entry:
@@ -48,7 +48,7 @@ entry:
ret void
}
; CHECK: atomic8_store_monotonic
-; CHECK: call void @__tsan_atomic8_store(i8* %a, i8 0, i32 1)
+; CHECK: call void @__tsan_atomic8_store(i8* %a, i8 0, i32 100501)
define void @atomic8_store_release(i8* %a) nounwind uwtable {
entry:
@@ -56,7 +56,7 @@ entry:
ret void
}
; CHECK: atomic8_store_release
-; CHECK: call void @__tsan_atomic8_store(i8* %a, i8 0, i32 8)
+; CHECK: call void @__tsan_atomic8_store(i8* %a, i8 0, i32 100508)
define void @atomic8_store_seq_cst(i8* %a) nounwind uwtable {
entry:
@@ -64,7 +64,7 @@ entry:
ret void
}
; CHECK: atomic8_store_seq_cst
-; CHECK: call void @__tsan_atomic8_store(i8* %a, i8 0, i32 32)
+; CHECK: call void @__tsan_atomic8_store(i8* %a, i8 0, i32 100532)
define i16 @atomic16_load_unordered(i16* %a) nounwind uwtable {
entry:
@@ -72,7 +72,7 @@ entry:
ret i16 %0
}
; CHECK: atomic16_load_unordered
-; CHECK: call i16 @__tsan_atomic16_load(i16* %a, i32 1)
+; CHECK: call i16 @__tsan_atomic16_load(i16* %a, i32 100501)
define i16 @atomic16_load_monotonic(i16* %a) nounwind uwtable {
entry:
@@ -80,7 +80,7 @@ entry:
ret i16 %0
}
; CHECK: atomic16_load_monotonic
-; CHECK: call i16 @__tsan_atomic16_load(i16* %a, i32 1)
+; CHECK: call i16 @__tsan_atomic16_load(i16* %a, i32 100501)
define i16 @atomic16_load_acquire(i16* %a) nounwind uwtable {
entry:
@@ -88,7 +88,7 @@ entry:
ret i16 %0
}
; CHECK: atomic16_load_acquire
-; CHECK: call i16 @__tsan_atomic16_load(i16* %a, i32 4)
+; CHECK: call i16 @__tsan_atomic16_load(i16* %a, i32 100504)
define i16 @atomic16_load_seq_cst(i16* %a) nounwind uwtable {
entry:
@@ -96,7 +96,7 @@ entry:
ret i16 %0
}
; CHECK: atomic16_load_seq_cst
-; CHECK: call i16 @__tsan_atomic16_load(i16* %a, i32 32)
+; CHECK: call i16 @__tsan_atomic16_load(i16* %a, i32 100532)
define void @atomic16_store_unordered(i16* %a) nounwind uwtable {
entry:
@@ -104,7 +104,7 @@ entry:
ret void
}
; CHECK: atomic16_store_unordered
-; CHECK: call void @__tsan_atomic16_store(i16* %a, i16 0, i32 1)
+; CHECK: call void @__tsan_atomic16_store(i16* %a, i16 0, i32 100501)
define void @atomic16_store_monotonic(i16* %a) nounwind uwtable {
entry:
@@ -112,7 +112,7 @@ entry:
ret void
}
; CHECK: atomic16_store_monotonic
-; CHECK: call void @__tsan_atomic16_store(i16* %a, i16 0, i32 1)
+; CHECK: call void @__tsan_atomic16_store(i16* %a, i16 0, i32 100501)
define void @atomic16_store_release(i16* %a) nounwind uwtable {
entry:
@@ -120,7 +120,7 @@ entry:
ret void
}
; CHECK: atomic16_store_release
-; CHECK: call void @__tsan_atomic16_store(i16* %a, i16 0, i32 8)
+; CHECK: call void @__tsan_atomic16_store(i16* %a, i16 0, i32 100508)
define void @atomic16_store_seq_cst(i16* %a) nounwind uwtable {
entry:
@@ -128,7 +128,7 @@ entry:
ret void
}
; CHECK: atomic16_store_seq_cst
-; CHECK: call void @__tsan_atomic16_store(i16* %a, i16 0, i32 32)
+; CHECK: call void @__tsan_atomic16_store(i16* %a, i16 0, i32 100532)
define i32 @atomic32_load_unordered(i32* %a) nounwind uwtable {
entry:
@@ -136,7 +136,7 @@ entry:
ret i32 %0
}
; CHECK: atomic32_load_unordered
-; CHECK: call i32 @__tsan_atomic32_load(i32* %a, i32 1)
+; CHECK: call i32 @__tsan_atomic32_load(i32* %a, i32 100501)
define i32 @atomic32_load_monotonic(i32* %a) nounwind uwtable {
entry:
@@ -144,7 +144,7 @@ entry:
ret i32 %0
}
; CHECK: atomic32_load_monotonic
-; CHECK: call i32 @__tsan_atomic32_load(i32* %a, i32 1)
+; CHECK: call i32 @__tsan_atomic32_load(i32* %a, i32 100501)
define i32 @atomic32_load_acquire(i32* %a) nounwind uwtable {
entry:
@@ -152,7 +152,7 @@ entry:
ret i32 %0
}
; CHECK: atomic32_load_acquire
-; CHECK: call i32 @__tsan_atomic32_load(i32* %a, i32 4)
+; CHECK: call i32 @__tsan_atomic32_load(i32* %a, i32 100504)
define i32 @atomic32_load_seq_cst(i32* %a) nounwind uwtable {
entry:
@@ -160,7 +160,7 @@ entry:
ret i32 %0
}
; CHECK: atomic32_load_seq_cst
-; CHECK: call i32 @__tsan_atomic32_load(i32* %a, i32 32)
+; CHECK: call i32 @__tsan_atomic32_load(i32* %a, i32 100532)
define void @atomic32_store_unordered(i32* %a) nounwind uwtable {
entry:
@@ -168,7 +168,7 @@ entry:
ret void
}
; CHECK: atomic32_store_unordered
-; CHECK: call void @__tsan_atomic32_store(i32* %a, i32 0, i32 1)
+; CHECK: call void @__tsan_atomic32_store(i32* %a, i32 0, i32 100501)
define void @atomic32_store_monotonic(i32* %a) nounwind uwtable {
entry:
@@ -176,7 +176,7 @@ entry:
ret void
}
; CHECK: atomic32_store_monotonic
-; CHECK: call void @__tsan_atomic32_store(i32* %a, i32 0, i32 1)
+; CHECK: call void @__tsan_atomic32_store(i32* %a, i32 0, i32 100501)
define void @atomic32_store_release(i32* %a) nounwind uwtable {
entry:
@@ -184,7 +184,7 @@ entry:
ret void
}
; CHECK: atomic32_store_release
-; CHECK: call void @__tsan_atomic32_store(i32* %a, i32 0, i32 8)
+; CHECK: call void @__tsan_atomic32_store(i32* %a, i32 0, i32 100508)
define void @atomic32_store_seq_cst(i32* %a) nounwind uwtable {
entry:
@@ -192,7 +192,7 @@ entry:
ret void
}
; CHECK: atomic32_store_seq_cst
-; CHECK: call void @__tsan_atomic32_store(i32* %a, i32 0, i32 32)
+; CHECK: call void @__tsan_atomic32_store(i32* %a, i32 0, i32 100532)
define i64 @atomic64_load_unordered(i64* %a) nounwind uwtable {
entry:
@@ -200,7 +200,7 @@ entry:
ret i64 %0
}
; CHECK: atomic64_load_unordered
-; CHECK: call i64 @__tsan_atomic64_load(i64* %a, i32 1)
+; CHECK: call i64 @__tsan_atomic64_load(i64* %a, i32 100501)
define i64 @atomic64_load_monotonic(i64* %a) nounwind uwtable {
entry:
@@ -208,7 +208,7 @@ entry:
ret i64 %0
}
; CHECK: atomic64_load_monotonic
-; CHECK: call i64 @__tsan_atomic64_load(i64* %a, i32 1)
+; CHECK: call i64 @__tsan_atomic64_load(i64* %a, i32 100501)
define i64 @atomic64_load_acquire(i64* %a) nounwind uwtable {
entry:
@@ -216,7 +216,7 @@ entry:
ret i64 %0
}
; CHECK: atomic64_load_acquire
-; CHECK: call i64 @__tsan_atomic64_load(i64* %a, i32 4)
+; CHECK: call i64 @__tsan_atomic64_load(i64* %a, i32 100504)
define i64 @atomic64_load_seq_cst(i64* %a) nounwind uwtable {
entry:
@@ -224,7 +224,7 @@ entry:
ret i64 %0
}
; CHECK: atomic64_load_seq_cst
-; CHECK: call i64 @__tsan_atomic64_load(i64* %a, i32 32)
+; CHECK: call i64 @__tsan_atomic64_load(i64* %a, i32 100532)
define void @atomic64_store_unordered(i64* %a) nounwind uwtable {
entry:
@@ -232,7 +232,7 @@ entry:
ret void
}
; CHECK: atomic64_store_unordered
-; CHECK: call void @__tsan_atomic64_store(i64* %a, i64 0, i32 1)
+; CHECK: call void @__tsan_atomic64_store(i64* %a, i64 0, i32 100501)
define void @atomic64_store_monotonic(i64* %a) nounwind uwtable {
entry:
@@ -240,7 +240,7 @@ entry:
ret void
}
; CHECK: atomic64_store_monotonic
-; CHECK: call void @__tsan_atomic64_store(i64* %a, i64 0, i32 1)
+; CHECK: call void @__tsan_atomic64_store(i64* %a, i64 0, i32 100501)
define void @atomic64_store_release(i64* %a) nounwind uwtable {
entry:
@@ -248,7 +248,7 @@ entry:
ret void
}
; CHECK: atomic64_store_release
-; CHECK: call void @__tsan_atomic64_store(i64* %a, i64 0, i32 8)
+; CHECK: call void @__tsan_atomic64_store(i64* %a, i64 0, i32 100508)
define void @atomic64_store_seq_cst(i64* %a) nounwind uwtable {
entry:
@@ -256,7 +256,7 @@ entry:
ret void
}
; CHECK: atomic64_store_seq_cst
-; CHECK: call void @__tsan_atomic64_store(i64* %a, i64 0, i32 32)
+; CHECK: call void @__tsan_atomic64_store(i64* %a, i64 0, i32 100532)
define i128 @atomic128_load_unordered(i128* %a) nounwind uwtable {
entry:
@@ -264,7 +264,7 @@ entry:
ret i128 %0
}
; CHECK: atomic128_load_unordered
-; CHECK: call i128 @__tsan_atomic128_load(i128* %a, i32 1)
+; CHECK: call i128 @__tsan_atomic128_load(i128* %a, i32 100501)
define i128 @atomic128_load_monotonic(i128* %a) nounwind uwtable {
entry:
@@ -272,7 +272,7 @@ entry:
ret i128 %0
}
; CHECK: atomic128_load_monotonic
-; CHECK: call i128 @__tsan_atomic128_load(i128* %a, i32 1)
+; CHECK: call i128 @__tsan_atomic128_load(i128* %a, i32 100501)
define i128 @atomic128_load_acquire(i128* %a) nounwind uwtable {
entry:
@@ -280,7 +280,7 @@ entry:
ret i128 %0
}
; CHECK: atomic128_load_acquire
-; CHECK: call i128 @__tsan_atomic128_load(i128* %a, i32 4)
+; CHECK: call i128 @__tsan_atomic128_load(i128* %a, i32 100504)
define i128 @atomic128_load_seq_cst(i128* %a) nounwind uwtable {
entry:
@@ -288,7 +288,7 @@ entry:
ret i128 %0
}
; CHECK: atomic128_load_seq_cst
-; CHECK: call i128 @__tsan_atomic128_load(i128* %a, i32 32)
+; CHECK: call i128 @__tsan_atomic128_load(i128* %a, i32 100532)
define void @atomic128_store_unordered(i128* %a) nounwind uwtable {
entry:
@@ -296,7 +296,7 @@ entry:
ret void
}
; CHECK: atomic128_store_unordered
-; CHECK: call void @__tsan_atomic128_store(i128* %a, i128 0, i32 1)
+; CHECK: call void @__tsan_atomic128_store(i128* %a, i128 0, i32 100501)
define void @atomic128_store_monotonic(i128* %a) nounwind uwtable {
entry:
@@ -304,7 +304,7 @@ entry:
ret void
}
; CHECK: atomic128_store_monotonic
-; CHECK: call void @__tsan_atomic128_store(i128* %a, i128 0, i32 1)
+; CHECK: call void @__tsan_atomic128_store(i128* %a, i128 0, i32 100501)
define void @atomic128_store_release(i128* %a) nounwind uwtable {
entry:
@@ -312,7 +312,7 @@ entry:
ret void
}
; CHECK: atomic128_store_release
-; CHECK: call void @__tsan_atomic128_store(i128* %a, i128 0, i32 8)
+; CHECK: call void @__tsan_atomic128_store(i128* %a, i128 0, i32 100508)
define void @atomic128_store_seq_cst(i128* %a) nounwind uwtable {
entry:
@@ -320,4 +320,4 @@ entry:
ret void
}
; CHECK: atomic128_store_seq_cst
-; CHECK: call void @__tsan_atomic128_store(i128* %a, i128 0, i32 32)
+; CHECK: call void @__tsan_atomic128_store(i128* %a, i128 0, i32 100532)
diff --git a/test/MC/MachO/lit.local.cfg b/test/MC/MachO/lit.local.cfg
index 6c49f08b74..41a8434f99 100644
--- a/test/MC/MachO/lit.local.cfg
+++ b/test/MC/MachO/lit.local.cfg
@@ -1,4 +1,4 @@
-config.suffixes = ['.s']
+config.suffixes = ['.s', '.ll']
targets = set(config.root.targets_to_build.split())
if not 'X86' in targets:
diff --git a/test/MC/MachO/x86-data-in-code.ll b/test/MC/MachO/x86-data-in-code.ll
new file mode 100644
index 0000000000..2410974c5c
--- /dev/null
+++ b/test/MC/MachO/x86-data-in-code.ll
@@ -0,0 +1,108 @@
+; RUN: llc -O0 -mtriple=x86_64-apple-darwin -filetype=obj -o - %s | macho-dump | FileCheck %s
+
+; There should not be a data-in-code load command (type 0x29) for x86_64
+; jump tables, even though they are in the text section.
+; CHECK: 'num_load_commands'
+; CHECK-NOT: (('command', 41)
+
+define void @foo(i32* %ptr) nounwind ssp {
+ %tmp = load i32* %ptr, align 4
+ switch i32 %tmp, label %default [
+ i32 11, label %bb0
+ i32 10, label %bb1
+ i32 8, label %bb2
+ i32 4, label %bb3
+ i32 2, label %bb4
+ i32 6, label %bb5
+ i32 9, label %bb6
+ i32 15, label %bb7
+ i32 1, label %bb8
+ i32 3, label %bb9
+ i32 5, label %bb10
+ i32 30, label %bb11
+ i32 31, label %bb12
+ i32 13, label %bb13
+ i32 14, label %bb14
+ i32 20, label %bb15
+ i32 19, label %bb16
+ i32 17, label %bb17
+ i32 18, label %bb18
+ i32 21, label %bb19
+ i32 22, label %bb20
+ i32 16, label %bb21
+ i32 24, label %bb22
+ i32 25, label %bb23
+ i32 26, label %bb24
+ i32 27, label %bb25
+ i32 28, label %bb26
+ i32 23, label %bb27
+ i32 12, label %bb28
+ ]
+
+default:
+ br label %exit
+bb0:
+ br label %exit
+bb1:
+ br label %exit
+bb2:
+ br label %exit
+bb3:
+ br label %exit
+bb4:
+ br label %exit
+bb5:
+ br label %exit
+bb6:
+ br label %exit
+bb7:
+ br label %exit
+bb8:
+ br label %exit
+bb9:
+ br label %exit
+bb10:
+ br label %exit
+bb11:
+ br label %exit
+bb12:
+ br label %exit
+bb13:
+ br label %exit
+bb14:
+ br label %exit
+bb15:
+ br label %exit
+bb16:
+ br label %exit
+bb17:
+ br label %exit
+bb18:
+ br label %exit
+bb19:
+ br label %exit
+bb20:
+ br label %exit
+bb21:
+ br label %exit
+bb22:
+ br label %exit
+bb23:
+ br label %exit
+bb24:
+ br label %exit
+bb25:
+ br label %exit
+bb26:
+ br label %exit
+bb27:
+ br label %exit
+bb28:
+ br label %exit
+
+
+exit:
+
+ ret void
+}
+
diff --git a/test/MC/Mips/mips-expansions.s b/test/MC/Mips/mips-expansions.s
new file mode 100644
index 0000000000..b87bfbdc5b
--- /dev/null
+++ b/test/MC/Mips/mips-expansions.s
@@ -0,0 +1,14 @@
+# RUN: llvm-mc %s -triple=mipsel-unknown-linux -show-encoding -mcpu=mips32r2 | FileCheck %s
+# Check that the assembler can handle the documented syntax
+# for macro instructions
+# CHECK: .section __TEXT,__text,regular,pure_instructions
+#------------------------------------------------------------------------------
+# Load immediate instructions
+#------------------------------------------------------------------------------
+# CHECK: ori $5, $zero, 123 # encoding: [0x7b,0x00,0x05,0x34]
+# CHECK: addiu $6, $zero, -2345 # encoding: [0xd7,0xf6,0x06,0x24]
+# CHECK: lui $7, 1 # encoding: [0x01,0x00,0x07,0x3c]
+# CHECK: ori $7, $7, 2 # encoding: [0x02,0x00,0xe7,0x34]
+ li $5,123
+ li $6,-2345
+ li $7,65538
diff --git a/test/MC/Mips/mips-fpu-instructions.s b/test/MC/Mips/mips-fpu-instructions.s
index ce8024d45b..a126c6f718 100644
--- a/test/MC/Mips/mips-fpu-instructions.s
+++ b/test/MC/Mips/mips-fpu-instructions.s
@@ -149,6 +149,14 @@
# CHECK: mthi $7 # encoding: [0x11,0x00,0xe0,0x00]
# CHECK: mtlo $7 # encoding: [0x13,0x00,0xe0,0x00]
# CHECK: swc1 $f9, 9158($7) # encoding: [0xc6,0x23,0xe9,0xe4]
+# CHECK: mfc0 $6, $7, 0 # encoding: [0x00,0x38,0x06,0x40]
+# CHECK: mtc0 $9, $8, 0 # encoding: [0x00,0x40,0x89,0x40]
+# CHECK: mfc2 $5, $7, 0 # encoding: [0x00,0x38,0x05,0x48]
+# CHECK: mtc2 $9, $4, 0 # encoding: [0x00,0x20,0x89,0x48]
+# CHECK: mfc0 $6, $7, 2 # encoding: [0x02,0x38,0x06,0x40]
+# CHECK: mtc0 $9, $8, 3 # encoding: [0x03,0x40,0x89,0x40]
+# CHECK: mfc2 $5, $7, 4 # encoding: [0x04,0x38,0x05,0x48]
+# CHECK: mtc2 $9, $4, 5 # encoding: [0x05,0x20,0x89,0x48]
cfc1 $a2,$0
mfc1 $a2,$f7
@@ -160,3 +168,11 @@
mthi $a3
mtlo $a3
swc1 $f9,9158($a3)
+ mfc0 $6, $7
+ mtc0 $9, $8
+ mfc2 $5, $7
+ mtc2 $9, $4
+ mfc0 $6, $7, 2
+ mtc0 $9, $8, 3
+ mfc2 $5, $7, 4
+ mtc2 $9, $4, 5
diff --git a/test/MC/Mips/mips_directives.s b/test/MC/Mips/mips_directives.s
index f9d846078b..e2f75a827d 100644
--- a/test/MC/Mips/mips_directives.s
+++ b/test/MC/Mips/mips_directives.s
@@ -1,10 +1,16 @@
# RUN: llvm-mc -triple mips-unknown-unknown %s
-
+#this test produces no output so there isS no FileCheck call
$BB0_2:
+ .ent directives_test
.frame $sp,0,$ra
.mask 0x00000000,0
.fmask 0x00000000,0
.set noreorder
.set nomacro
+ .set noat
$JTI0_0:
.gpword ($BB0_2)
+ .set at=$12
+ .set macro
+ .set reorder
+ .end directives_test
diff --git a/test/Makefile b/test/Makefile
index ae7a67401f..3c6b5b68a4 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -29,11 +29,6 @@ else
LIT_ARGS := -s -v
endif
-# -jN causes crash on Cygwin's python.
-ifneq (,$(filter $(HOST_OS),Cygwin))
- LIT_ARGS += -j1
-endif
-
ifdef TESTSUITE
LIT_TESTSUITE := $(TESTSUITE)
CLEANED_TESTSUITE := $(patsubst %/,%,$(TESTSUITE))
diff --git a/test/Other/ResponseFile.ll b/test/Other/ResponseFile.ll
new file mode 100644
index 0000000000..b8b3d0a902
--- /dev/null
+++ b/test/Other/ResponseFile.ll
@@ -0,0 +1,9 @@
+; RUN: echo %s > %t.list
+; RUN: llvm-as @%t.list -o %t.bc
+; RUN: llvm-nm %t.bc 2>&1 | FileCheck %s
+
+; CHECK: T foobar
+
+define void @foobar() {
+ ret void
+}
diff --git a/test/Other/spir_cc.ll b/test/Other/spir_cc.ll
new file mode 100644
index 0000000000..ffc02945de
--- /dev/null
+++ b/test/Other/spir_cc.ll
@@ -0,0 +1,13 @@
+; RUN: llvm-as < %s | llvm-dis > %t1.ll
+; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll
+; RUN: diff %t1.ll %t2.ll
+
+define spir_func void @foo() {
+ ret void
+}
+
+define spir_kernel void @bar() {
+ call spir_func void @foo( )
+ call spir_kernel void @bar( )
+ ret void
+}
diff --git a/test/Transforms/DeadArgElim/dbginfo.ll b/test/Transforms/DeadArgElim/dbginfo.ll
new file mode 100644
index 0000000000..dcbfaaa3d7
--- /dev/null
+++ b/test/Transforms/DeadArgElim/dbginfo.ll
@@ -0,0 +1,64 @@
+; RUN: opt %s -deadargelim -S | FileCheck %s
+; PR14016
+
+; Check that debug info metadata for subprograms stores pointers to
+; updated LLVM functions.
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@x = global i32 0, align 4
+
+define void @_Z3runv() uwtable {
+entry:
+ call void @_ZN12_GLOBAL__N_18dead_argEPv(i8* null), !dbg !10
+ call void (...)* @_ZN12_GLOBAL__N_111dead_varargEz(), !dbg !12
+ ret void, !dbg !13
+}
+
+; Argument will be deleted
+define internal void @_ZN12_GLOBAL__N_18dead_argEPv(i8* %foo) nounwind uwtable {
+entry:
+ %0 = load i32* @x, align 4, !dbg !14
+ %inc = add nsw i32 %0, 1, !dbg !14
+ store i32 %inc, i32* @x, align 4, !dbg !14
+ ret void, !dbg !16
+}
+
+; Vararg will be deleted
+define internal void @_ZN12_GLOBAL__N_111dead_varargEz(...) nounwind uwtable {
+entry:
+ %0 = load i32* @x, align 4, !dbg !17
+ %inc = add nsw i32 %0, 1, !dbg !17
+ store i32 %inc, i32* @x, align 4, !dbg !17
+ ret void, !dbg !19
+}
+
+!llvm.dbg.cu = !{!0}
+
+!0 = metadata !{i32 786449, i32 0, i32 4, metadata !"test.cc", metadata !"/home/samsonov/tmp/clang-di", metadata !"clang version 3.2 (trunk 165305)", i1 true, i1 false, metadata !"", i32 0, metadata !1, metadata !1, metadata !3, metadata !1} ; [ DW_TAG_compile_unit ] [/home/samsonov/tmp/clang-di/test.cc] [DW_LANG_C_plus_plus]
+!1 = metadata !{metadata !2}
+!2 = metadata !{i32 0}
+!3 = metadata !{metadata !4}
+!4 = metadata !{metadata !5, metadata !8, metadata !9}
+!5 = metadata !{i32 786478, i32 0, metadata !6, metadata !"run", metadata !"run", metadata !"", metadata !6, i32 8, metadata !7, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void ()* @_Z3runv, null, null, metadata !1, i32 8} ; [ DW_TAG_subprogram ] [line 8] [def] [run]
+!6 = metadata !{i32 786473, metadata !"test.cc", metadata !"/home/samsonov/tmp/clang-di", null} ; [ DW_TAG_file_type ]
+!7 = metadata !{i32 786453, i32 0, metadata !"", i32 0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !2, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!8 = metadata !{i32 786478, i32 0, metadata !6, metadata !"dead_vararg", metadata !"dead_vararg", metadata !"", metadata !6, i32 5, metadata !7, i1 true, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (...)* @_ZN12_GLOBAL__N_111dead_varargEz, null, null, metadata !1, i32 5} ; [ DW_TAG_subprogram ] [line 5] [local] [def] [dead_vararg]
+
+; CHECK: metadata !"dead_vararg"{{.*}}void ()* @_ZN12_GLOBAL__N_111dead_varargEz
+
+!9 = metadata !{i32 786478, i32 0, metadata !6, metadata !"dead_arg", metadata !"dead_arg", metadata !"", metadata !6, i32 4, metadata !7, i1 true, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (i8*)* @_ZN12_GLOBAL__N_18dead_argEPv, null, null, metadata !1, i32 4} ; [ DW_TAG_subprogram ] [line 4] [local] [def] [dead_arg]
+
+; CHECK: metadata !"dead_arg"{{.*}}void ()* @_ZN12_GLOBAL__N_18dead_argEPv
+
+!10 = metadata !{i32 8, i32 14, metadata !11, null}
+!11 = metadata !{i32 786443, metadata !5, i32 8, i32 12, metadata !6, i32 0} ; [ DW_TAG_lexical_block ] [/home/samsonov/tmp/clang-di/test.cc]
+!12 = metadata !{i32 8, i32 27, metadata !11, null}
+!13 = metadata !{i32 8, i32 42, metadata !11, null}
+!14 = metadata !{i32 4, i32 28, metadata !15, null}
+!15 = metadata !{i32 786443, metadata !9, i32 4, i32 26, metadata !6, i32 2} ; [ DW_TAG_lexical_block ] [/home/samsonov/tmp/clang-di/test.cc]
+!16 = metadata !{i32 4, i32 33, metadata !15, null}
+!17 = metadata !{i32 5, i32 25, metadata !18, null}
+!18 = metadata !{i32 786443, metadata !8, i32 5, i32 23, metadata !6, i32 1} ; [ DW_TAG_lexical_block ] [/home/samsonov/tmp/clang-di/test.cc]
+!19 = metadata !{i32 5, i32 30, metadata !18, null}
diff --git a/test/Transforms/EarlyCSE/commute.ll b/test/Transforms/EarlyCSE/commute.ll
new file mode 100644
index 0000000000..f84a7dd1aa
--- /dev/null
+++ b/test/Transforms/EarlyCSE/commute.ll
@@ -0,0 +1,66 @@
+; RUN: opt < %s -S -early-cse | FileCheck %s
+
+; CHECK: @test1
+define void @test1(float %A, float %B, float* %PA, float* %PB) {
+ ; CHECK-NEXT: fadd
+ ; CHECK-NEXT: store
+ ; CHECK-NEXT: store
+ ; CHECK-NEXT: ret
+ %C = fadd float %A, %B
+ store float %C, float* %PA
+ %D = fadd float %B, %A
+ store float %D, float* %PB
+ ret void
+}
+
+; CHECK: @test2
+define void @test2(float %A, float %B, i1* %PA, i1* %PB) {
+ ; CHECK-NEXT: fcmp
+ ; CHECK-NEXT: store
+ ; CHECK-NEXT: store
+ ; CHECK-NEXT: ret
+ %C = fcmp eq float %A, %B
+ store i1 %C, i1* %PA
+ %D = fcmp eq float %B, %A
+ store i1 %D, i1* %PB
+ ret void
+}
+
+; CHECK: @test3
+define void @test3(float %A, float %B, i1* %PA, i1* %PB) {
+ ; CHECK-NEXT: fcmp
+ ; CHECK-NEXT: store
+ ; CHECK-NEXT: store
+ ; CHECK-NEXT: ret
+ %C = fcmp uge float %A, %B
+ store i1 %C, i1* %PA
+ %D = fcmp ule float %B, %A
+ store i1 %D, i1* %PB
+ ret void
+}
+
+; CHECK: @test4
+define void @test4(i32 %A, i32 %B, i1* %PA, i1* %PB) {
+ ; CHECK-NEXT: icmp
+ ; CHECK-NEXT: store
+ ; CHECK-NEXT: store
+ ; CHECK-NEXT: ret
+ %C = icmp eq i32 %A, %B
+ store i1 %C, i1* %PA
+ %D = icmp eq i32 %B, %A
+ store i1 %D, i1* %PB
+ ret void
+}
+
+; CHECK: @test5
+define void @test5(i32 %A, i32 %B, i1* %PA, i1* %PB) {
+ ; CHECK-NEXT: icmp
+ ; CHECK-NEXT: store
+ ; CHECK-NEXT: store
+ ; CHECK-NEXT: ret
+ %C = icmp sgt i32 %A, %B
+ store i1 %C, i1* %PA
+ %D = icmp slt i32 %B, %A
+ store i1 %D, i1* %PB
+ ret void
+}
diff --git a/test/Transforms/IndVarSimplify/2004-04-05-InvokeCastCrash.ll b/test/Transforms/IndVarSimplify/2004-04-05-InvokeCastCrash.ll
index 708a961272..0c88e83975 100644
--- a/test/Transforms/IndVarSimplify/2004-04-05-InvokeCastCrash.ll
+++ b/test/Transforms/IndVarSimplify/2004-04-05-InvokeCastCrash.ll
@@ -39,11 +39,11 @@
%"struct.llvm::SymbolTable" = type opaque
%"struct.llvm::SymbolTableListTraits<llvm::Argument,llvm::Function,llvm::Function,llvm::ilist_traits<llvm::Argument> >" = type { %"struct.llvm::Function"*, %"struct.llvm::Function"* }
%"struct.llvm::SymbolTableListTraits<llvm::Instruction,llvm::BasicBlock,llvm::Function,llvm::ilist_traits<llvm::Instruction> >" = type { %"struct.llvm::Function"*, %"struct.llvm::BasicBlock"* }
- %"struct.llvm::TargetData" = type { %"struct.llvm::FunctionPass", i1, i8, i8, i8, i8, i8, i8, i8, i8 }
+ %"struct.llvm::DataLayout" = type { %"struct.llvm::FunctionPass", i1, i8, i8, i8, i8, i8, i8, i8, i8 }
%"struct.llvm::TargetFrameInfo" = type { i32 (...)**, i32, i32, i32 }
%"struct.llvm::TargetInstrDescriptor" = type { i8*, i32, i32, i32, i1, i32, i32, i32, i32, i32, i32*, i32* }
%"struct.llvm::TargetInstrInfo" = type { i32 (...)**, %"struct.llvm::TargetInstrDescriptor"*, i32, i32 }
- %"struct.llvm::TargetMachine" = type { i32 (...)**, %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >", %"struct.llvm::TargetData", %"struct.llvm::IntrinsicLowering"* }
+ %"struct.llvm::TargetMachine" = type { i32 (...)**, %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >", %"struct.llvm::DataLayout", %"struct.llvm::IntrinsicLowering"* }
%"struct.llvm::TargetRegClassInfo" = type { i32 (...)**, i32, i32, i32 }
%"struct.llvm::TargetRegInfo" = type { i32 (...)**, %"struct.std::vector<const llvm::TargetRegClassInfo*,std::allocator<const llvm::TargetRegClassInfo*> >", %"struct.llvm::TargetMachine"* }
%"struct.llvm::Type" = type { %"struct.llvm::Value", i32, i32, i1, i32, %"struct.llvm::Type"*, %"struct.std::vector<llvm::PATypeHandle,std::allocator<llvm::PATypeHandle> >" }
diff --git a/test/Transforms/IndVarSimplify/crash.ll b/test/Transforms/IndVarSimplify/crash.ll
index 3335be781d..62af42b9d6 100644
--- a/test/Transforms/IndVarSimplify/crash.ll
+++ b/test/Transforms/IndVarSimplify/crash.ll
@@ -87,3 +87,29 @@ entry:
main.f.exit: ; preds = %"3.i"
unreachable
}
+
+
+; PR13967
+
+define void @f() nounwind ssp {
+bb:
+ br label %bb4
+
+bb4:
+ %tmp = phi i64 [ %tmp5, %bb7 ], [ undef, %bb ]
+ %tmp5 = add nsw i64 %tmp, 1
+ %extract.t1 = trunc i64 %tmp5 to i32
+ br i1 false, label %bb6, label %bb7
+
+bb6:
+ br label %bb7
+
+bb7:
+ %.off0 = phi i32 [ undef, %bb6 ], [ %extract.t1, %bb4 ]
+ %tmp8 = icmp eq i32 %.off0, 0
+ br i1 %tmp8, label %bb9, label %bb4
+
+bb9:
+ ret void
+}
+
diff --git a/test/Transforms/InstCombine/align-addr.ll b/test/Transforms/InstCombine/align-addr.ll
index 27916b9860..4ea1bd9beb 100644
--- a/test/Transforms/InstCombine/align-addr.ll
+++ b/test/Transforms/InstCombine/align-addr.ll
@@ -58,3 +58,19 @@ define double @test2(double* %p, double %n) nounwind {
store double %n, double* %p
ret double %t
}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
+
+declare void @use(i8*)
+
+%struct.s = type { i32, i32, i32, i32 }
+
+define void @test3(%struct.s* sret %a4) {
+; Check that the alignment is bumped up the alignment of the sret type.
+; CHECK: @test3
+ %a4.cast = bitcast %struct.s* %a4 to i8*
+ call void @llvm.memset.p0i8.i64(i8* %a4.cast, i8 0, i64 16, i32 1, i1 false)
+; CHECK: call void @llvm.memset.p0i8.i64(i8* %a4.cast, i8 0, i64 16, i32 4, i1 false)
+ call void @use(i8* %a4.cast)
+ ret void
+}
diff --git a/test/Transforms/InstCombine/and-fcmp.ll b/test/Transforms/InstCombine/and-fcmp.ll
index 838c2f73fb..40c44c09a8 100644
--- a/test/Transforms/InstCombine/and-fcmp.ll
+++ b/test/Transforms/InstCombine/and-fcmp.ll
@@ -10,7 +10,7 @@ define zeroext i8 @t1(float %x, float %y) nounwind {
; CHECK: fcmp oeq float %x, %y
; CHECK-NOT: fcmp ueq float %x, %y
; CHECK-NOT: fcmp ord float %x, %y
-; CHECK-NOW: and
+; CHECK-NOT: and
}
define zeroext i8 @t2(float %x, float %y) nounwind {
diff --git a/test/Transforms/MemCpyOpt/2008-03-13-ReturnSlotBitcast.ll b/test/Transforms/MemCpyOpt/2008-03-13-ReturnSlotBitcast.ll
index 61ba3c7e6c..597b69dee3 100644
--- a/test/Transforms/MemCpyOpt/2008-03-13-ReturnSlotBitcast.ll
+++ b/test/Transforms/MemCpyOpt/2008-03-13-ReturnSlotBitcast.ll
@@ -9,11 +9,11 @@ declare void @g(%a*)
define float @f() {
entry:
%a_var = alloca %a
- %b_var = alloca %b
+ %b_var = alloca %b, align 1
call void @g(%a* %a_var)
%a_i8 = bitcast %a* %a_var to i8*
%b_i8 = bitcast %b* %b_var to i8*
- call void @llvm.memcpy.p0i8.p0i8.i32(i8* %b_i8, i8* %a_i8, i32 4, i32 4, i1 false)
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* %b_i8, i8* %a_i8, i32 4, i32 1, i1 false)
%tmp1 = getelementptr %b* %b_var, i32 0, i32 0
%tmp2 = load float* %tmp1
ret float %tmp2
diff --git a/test/Transforms/MemCpyOpt/align.ll b/test/Transforms/MemCpyOpt/align.ll
index b1f900d9da..1b98f6ad38 100644
--- a/test/Transforms/MemCpyOpt/align.ll
+++ b/test/Transforms/MemCpyOpt/align.ll
@@ -1,12 +1,15 @@
-; RUN: opt < %s -S -memcpyopt | FileCheck %s
+; RUN: opt < %s -S -basicaa -memcpyopt | FileCheck %s
target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64"
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
+
; The resulting memset is only 4-byte aligned, despite containing
; a 16-byte aligned store in the middle.
-; CHECK: call void @llvm.memset.p0i8.i64(i8* {{.*}}, i8 0, i64 16, i32 4, i1 false)
-
define void @foo(i32* %p) {
+; CHECK: @foo
+; CHECK: call void @llvm.memset.p0i8.i64(i8* {{.*}}, i8 0, i64 16, i32 4, i1 false)
%a0 = getelementptr i32* %p, i64 0
store i32 0, i32* %a0, align 4
%a1 = getelementptr i32* %p, i64 1
@@ -17,3 +20,18 @@ define void @foo(i32* %p) {
store i32 0, i32* %a3, align 4
ret void
}
+
+; Replacing %a8 with %a4 in the memset requires boosting the alignment of %a4.
+
+define void @bar() {
+; CHECK: @bar
+; CHECK: %a4 = alloca i32, align 8
+; CHECK-NOT: memcpy
+ %a4 = alloca i32, align 4
+ %a8 = alloca i32, align 8
+ %a8.cast = bitcast i32* %a8 to i8*
+ %a4.cast = bitcast i32* %a4 to i8*
+ call void @llvm.memset.p0i8.i64(i8* %a8.cast, i8 0, i64 4, i32 8, i1 false)
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a4.cast, i8* %a8.cast, i64 4, i32 4, i1 false)
+ ret void
+}
diff --git a/test/Transforms/SROA/alignment.ll b/test/Transforms/SROA/alignment.ll
index 02a67551a3..945ad91002 100644
--- a/test/Transforms/SROA/alignment.ll
+++ b/test/Transforms/SROA/alignment.ll
@@ -1,5 +1,5 @@
; RUN: opt < %s -sroa -S | FileCheck %s
-target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1)
@@ -31,8 +31,8 @@ entry:
define void @test2() {
; CHECK: @test2
; CHECK: alloca i16
-; CHECK: load i8* %{{.*}}, align 1
-; CHECK: store i8 42, i8* %{{.*}}, align 1
+; CHECK: load i8* %{{.*}}
+; CHECK: store i8 42, i8* %{{.*}}
; CHECK: ret void
entry:
@@ -41,8 +41,8 @@ entry:
%cast1 = bitcast i8* %gep1 to i16*
store volatile i16 0, i16* %cast1
%gep2 = getelementptr { i8, i8, i8, i8 }* %a, i32 0, i32 2
- %result = load i8* %gep2, align 2
- store i8 42, i8* %gep2, align 2
+ %result = load i8* %gep2
+ store i8 42, i8* %gep2
ret void
}
@@ -83,3 +83,120 @@ entry:
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %b_gep, i8* %x, i32 18, i32 2, i1 false)
ret void
}
+
+%struct.S = type { i8, { i64 } }
+
+define void @test4() {
+; This test case triggered very strange alignment behavior with memcpy due to
+; strange splitting. Reported by Duncan.
+; CHECK: @test4
+
+entry:
+ %D.2113 = alloca %struct.S
+ %Op = alloca %struct.S
+ %D.2114 = alloca %struct.S
+ %gep1 = getelementptr inbounds %struct.S* %Op, i32 0, i32 0
+ store i8 0, i8* %gep1, align 8
+ %gep2 = getelementptr inbounds %struct.S* %Op, i32 0, i32 1, i32 0
+ %cast = bitcast i64* %gep2 to double*
+ store double 0.000000e+00, double* %cast, align 8
+ store i64 0, i64* %gep2, align 8
+ %dst1 = bitcast %struct.S* %D.2114 to i8*
+ %src1 = bitcast %struct.S* %Op to i8*
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst1, i8* %src1, i32 16, i32 8, i1 false)
+ %dst2 = bitcast %struct.S* %D.2113 to i8*
+ %src2 = bitcast %struct.S* %D.2114 to i8*
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst2, i8* %src2, i32 16, i32 8, i1 false)
+; We get 3 memcpy calls with various reasons to shrink their alignment to 1.
+; CHECK: @llvm.memcpy.p0i8.p0i8.i32(i8* %{{.*}}, i8* %{{.*}}, i32 3, i32 1, i1 false)
+; CHECK: @llvm.memcpy.p0i8.p0i8.i32(i8* %{{.*}}, i8* %{{.*}}, i32 8, i32 1, i1 false)
+; CHECK: @llvm.memcpy.p0i8.p0i8.i32(i8* %{{.*}}, i8* %{{.*}}, i32 11, i32 1, i1 false)
+
+ ret void
+}
+
+define void @test5() {
+; Test that we preserve underaligned loads and stores when splitting.
+; CHECK: @test5
+; CHECK: alloca [9 x i8]
+; CHECK: alloca [9 x i8]
+; CHECK: store volatile double 0.0{{.*}}, double* %{{.*}}, align 1
+; CHECK: load i16* %{{.*}}, align 1
+; CHECK: load double* %{{.*}}, align 1
+; CHECK: store volatile double %{{.*}}, double* %{{.*}}, align 1
+; CHECK: load i16* %{{.*}}, align 1
+; CHECK: ret void
+
+entry:
+ %a = alloca [18 x i8]
+ %raw1 = getelementptr inbounds [18 x i8]* %a, i32 0, i32 0
+ %ptr1 = bitcast i8* %raw1 to double*
+ store volatile double 0.0, double* %ptr1, align 1
+ %weird_gep1 = getelementptr inbounds [18 x i8]* %a, i32 0, i32 7
+ %weird_cast1 = bitcast i8* %weird_gep1 to i16*
+ %weird_load1 = load i16* %weird_cast1, align 1
+
+ %raw2 = getelementptr inbounds [18 x i8]* %a, i32 0, i32 9
+ %ptr2 = bitcast i8* %raw2 to double*
+ %d1 = load double* %ptr1, align 1
+ store volatile double %d1, double* %ptr2, align 1
+ %weird_gep2 = getelementptr inbounds [18 x i8]* %a, i32 0, i32 16
+ %weird_cast2 = bitcast i8* %weird_gep2 to i16*
+ %weird_load2 = load i16* %weird_cast2, align 1
+
+ ret void
+}
+
+define void @test6() {
+; Test that we promote alignment when the underlying alloca switches to one
+; that innately provides it.
+; CHECK: @test6
+; CHECK: alloca double
+; CHECK: alloca double
+; CHECK-NOT: align
+; CHECK: ret void
+
+entry:
+ %a = alloca [16 x i8]
+ %raw1 = getelementptr inbounds [16 x i8]* %a, i32 0, i32 0
+ %ptr1 = bitcast i8* %raw1 to double*
+ store volatile double 0.0, double* %ptr1, align 1
+
+ %raw2 = getelementptr inbounds [16 x i8]* %a, i32 0, i32 8
+ %ptr2 = bitcast i8* %raw2 to double*
+ %val = load double* %ptr1, align 1
+ store volatile double %val, double* %ptr2, align 1
+
+ ret void
+}
+
+define void @test7(i8* %out) {
+; Test that we properly compute the destination alignment when rewriting
+; memcpys as direct loads or stores.
+; CHECK: @test7
+; CHECK-NOT: alloca
+
+entry:
+ %a = alloca [16 x i8]
+ %raw1 = getelementptr inbounds [16 x i8]* %a, i32 0, i32 0
+ %ptr1 = bitcast i8* %raw1 to double*
+ %raw2 = getelementptr inbounds [16 x i8]* %a, i32 0, i32 8
+ %ptr2 = bitcast i8* %raw2 to double*
+
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* %raw1, i8* %out, i32 16, i32 0, i1 false)
+; CHECK: %[[val2:.*]] = load double* %{{.*}}, align 1
+; CHECK: %[[val1:.*]] = load double* %{{.*}}, align 1
+
+ %val1 = load double* %ptr2, align 1
+ %val2 = load double* %ptr1, align 1
+
+ store double %val1, double* %ptr1, align 1
+ store double %val2, double* %ptr2, align 1
+
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* %out, i8* %raw1, i32 16, i32 0, i1 false)
+; CHECK: store double %[[val1]], double* %{{.*}}, align 1
+; CHECK: store double %[[val2]], double* %{{.*}}, align 1
+
+ ret void
+; CHECK: ret void
+}
diff --git a/test/Transforms/SROA/basictest.ll b/test/Transforms/SROA/basictest.ll
index e58cef63ba..e7767ef5e9 100644
--- a/test/Transforms/SROA/basictest.ll
+++ b/test/Transforms/SROA/basictest.ll
@@ -1,7 +1,7 @@
; RUN: opt < %s -sroa -S | FileCheck %s
; RUN: opt < %s -sroa -force-ssa-updater -S | FileCheck %s
-target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
declare void @llvm.lifetime.start(i64, i8* nocapture)
declare void @llvm.lifetime.end(i64, i8* nocapture)
@@ -862,8 +862,7 @@ define void @PR13916.1() {
; Ensure that we handle overlapping memcpy intrinsics correctly, especially in
; the case where there is a directly identical value for both source and dest.
; CHECK: @PR13916.1
-; FIXME: We shouldn't leave this alloca around.
-; CHECK: alloca
+; CHECK-NOT: alloca
; CHECK: ret void
entry:
@@ -878,8 +877,7 @@ define void @PR13916.2() {
; different pointer value chains, but during rewriting we coalesce them into the
; same value.
; CHECK: @PR13916.2
-; FIXME: We shouldn't leave this alloca around.
-; CHECK: alloca
+; CHECK-NOT: alloca
; CHECK: ret void
entry:
@@ -897,3 +895,76 @@ if.end:
%tmp2 = load i8* %gep
ret void
}
+
+define void @PR13990() {
+; Ensure we can handle cases where processing one alloca causes the other
+; alloca to become dead and get deleted. This might crash or fail under
+; Valgrind if we regress.
+; CHECK: @PR13990
+; CHECK-NOT: alloca
+; CHECK: unreachable
+; CHECK: unreachable
+
+entry:
+ %tmp1 = alloca i8*
+ %tmp2 = alloca i8*
+ br i1 undef, label %bb1, label %bb2
+
+bb1:
+ store i8* undef, i8** %tmp2
+ br i1 undef, label %bb2, label %bb3
+
+bb2:
+ %tmp50 = select i1 undef, i8** %tmp2, i8** %tmp1
+ br i1 undef, label %bb3, label %bb4
+
+bb3:
+ unreachable
+
+bb4:
+ unreachable
+}
+
+define double @PR13969(double %x) {
+; Check that we detect when promotion will un-escape an alloca and iterate to
+; re-try running SROA over that alloca. Without that, the two allocas that are
+; stored into a dead alloca don't get rewritten and promoted.
+; CHECK: @PR13969
+
+entry:
+ %a = alloca double
+ %b = alloca double*
+ %c = alloca double
+; CHECK-NOT: alloca
+
+ store double %x, double* %a
+ store double* %c, double** %b
+ store double* %a, double** %b
+ store double %x, double* %c
+ %ret = load double* %a
+; CHECK-NOT: store
+; CHECK-NOT: load
+
+ ret double %ret
+; CHECK: ret double %x
+}
+
+%PR14034.struct = type { { {} }, i32, %PR14034.list }
+%PR14034.list = type { %PR14034.list*, %PR14034.list* }
+
+define void @PR14034() {
+; This test case tries to form GEPs into the empty leading struct members, and
+; subsequently crashed (under valgrind) before we fixed the PR. The important
+; thing is to handle empty structs gracefully.
+; CHECK: @PR14034
+
+entry:
+ %a = alloca %PR14034.struct
+ %list = getelementptr %PR14034.struct* %a, i32 0, i32 2
+ %prev = getelementptr %PR14034.list* %list, i32 0, i32 1
+ store %PR14034.list* undef, %PR14034.list** %prev
+ %cast0 = bitcast %PR14034.struct* undef to i8*
+ %cast1 = bitcast %PR14034.struct* %a to i8*
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* %cast0, i8* %cast1, i32 12, i32 0, i1 false)
+ ret void
+}
diff --git a/test/Transforms/SROA/big-endian.ll b/test/Transforms/SROA/big-endian.ll
new file mode 100644
index 0000000000..532f8690cf
--- /dev/null
+++ b/test/Transforms/SROA/big-endian.ll
@@ -0,0 +1,108 @@
+; RUN: opt < %s -sroa -S | FileCheck %s
+; RUN: opt < %s -sroa -force-ssa-updater -S | FileCheck %s
+
+target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
+
+define i8 @test1() {
+; We fully promote these to the i24 load or store size, resulting in just masks
+; and other operations that instcombine will fold, but no alloca. Note this is
+; the same as test12 in basictest.ll, but here we assert big-endian byte
+; ordering.
+;
+; CHECK: @test1
+
+entry:
+ %a = alloca [3 x i8]
+ %b = alloca [3 x i8]
+; CHECK-NOT: alloca
+
+ %a0ptr = getelementptr [3 x i8]* %a, i64 0, i32 0
+ store i8 0, i8* %a0ptr
+ %a1ptr = getelementptr [3 x i8]* %a, i64 0, i32 1
+ store i8 0, i8* %a1ptr
+ %a2ptr = getelementptr [3 x i8]* %a, i64 0, i32 2
+ store i8 0, i8* %a2ptr
+ %aiptr = bitcast [3 x i8]* %a to i24*
+ %ai = load i24* %aiptr
+; CHCEK-NOT: store
+; CHCEK-NOT: load
+; CHECK: %[[mask0:.*]] = and i24 undef, 65535
+; CHECK-NEXT: %[[mask1:.*]] = and i24 %[[mask0]], -65281
+; CHECK-NEXT: %[[mask2:.*]] = and i24 %[[mask1]], -256
+
+ %biptr = bitcast [3 x i8]* %b to i24*
+ store i24 %ai, i24* %biptr
+ %b0ptr = getelementptr [3 x i8]* %b, i64 0, i32 0
+ %b0 = load i8* %b0ptr
+ %b1ptr = getelementptr [3 x i8]* %b, i64 0, i32 1
+ %b1 = load i8* %b1ptr
+ %b2ptr = getelementptr [3 x i8]* %b, i64 0, i32 2
+ %b2 = load i8* %b2ptr
+; CHCEK-NOT: store
+; CHCEK-NOT: load
+; CHECK: %[[shift0:.*]] = lshr i24 %[[mask2]], 16
+; CHECK-NEXT: %[[trunc0:.*]] = trunc i24 %[[shift0]] to i8
+; CHECK-NEXT: %[[shift1:.*]] = lshr i24 %[[mask2]], 8
+; CHECK-NEXT: %[[trunc1:.*]] = trunc i24 %[[shift1]] to i8
+; CHECK-NEXT: %[[trunc2:.*]] = trunc i24 %[[mask2]] to i8
+
+ %bsum0 = add i8 %b0, %b1
+ %bsum1 = add i8 %bsum0, %b2
+ ret i8 %bsum1
+; CHECK: %[[sum0:.*]] = add i8 %[[trunc0]], %[[trunc1]]
+; CHECK-NEXT: %[[sum1:.*]] = add i8 %[[sum0]], %[[trunc2]]
+; CHECK-NEXT: ret i8 %[[sum1]]
+}
+
+define i64 @test2() {
+; Test for various mixed sizes of integer loads and stores all getting
+; promoted.
+;
+; CHECK: @test2
+
+entry:
+ %a = alloca [7 x i8]
+; CHECK-NOT: alloca
+
+ %a0ptr = getelementptr [7 x i8]* %a, i64 0, i32 0
+ %a1ptr = getelementptr [7 x i8]* %a, i64 0, i32 1
+ %a2ptr = getelementptr [7 x i8]* %a, i64 0, i32 2
+ %a3ptr = getelementptr [7 x i8]* %a, i64 0, i32 3
+
+; CHCEK-NOT: store
+; CHCEK-NOT: load
+
+ %a0i16ptr = bitcast i8* %a0ptr to i16*
+ store i16 1, i16* %a0i16ptr
+; CHECK: %[[mask:.*]] = and i56 undef, 1099511627775
+; CHECK-NEXT: %[[or:.*]] = or i56 %[[mask]], 1099511627776
+
+ %a1i4ptr = bitcast i8* %a1ptr to i4*
+ store i4 1, i4* %a1i4ptr
+; CHECK: %[[mask:.*]] = and i56 %[[or]], -16492674416641
+; CHECK-NEXT: %[[or:.*]] = or i56 %[[mask]], 1099511627776
+
+ store i8 1, i8* %a2ptr
+; CHECK-NEXT: %[[mask:.*]] = and i56 %[[or]], -1095216660481
+; CHECK-NEXT: %[[or:.*]] = or i56 %[[mask]], 4294967296
+
+ %a3i24ptr = bitcast i8* %a3ptr to i24*
+ store i24 1, i24* %a3i24ptr
+; CHECK-NEXT: %[[mask:.*]] = and i56 %[[or]], -4294967041
+; CHECK-NEXT: %[[or:.*]] = or i56 %[[mask]], 256
+
+ %a2i40ptr = bitcast i8* %a2ptr to i40*
+ store i40 1, i40* %a2i40ptr
+; CHECK-NEXT: %[[mask:.*]] = and i56 %[[or]], -1099511627776
+; CHECK-NEXT: %[[or:.*]] = or i56 %[[mask]], 1
+
+; CHCEK-NOT: store
+; CHCEK-NOT: load
+
+ %aiptr = bitcast [7 x i8]* %a to i56*
+ %ai = load i56* %aiptr
+ %ret = zext i56 %ai to i64
+ ret i64 %ret
+; CHECK: %[[ret:.*]] = zext i56 %[[or]] to i64
+; CHECK-NEXT: ret i64 %[[ret]]
+}
diff --git a/test/Transforms/SROA/fca.ll b/test/Transforms/SROA/fca.ll
index 6ddaed2f30..c30a5cc974 100644
--- a/test/Transforms/SROA/fca.ll
+++ b/test/Transforms/SROA/fca.ll
@@ -1,6 +1,6 @@
; RUN: opt < %s -sroa -S | FileCheck %s
; RUN: opt < %s -sroa -force-ssa-updater -S | FileCheck %s
-target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
define { i32, i32 } @test0(i32 %x, i32 %y) {
; CHECK: @test0
diff --git a/test/Transforms/SROA/phi-and-select.ll b/test/Transforms/SROA/phi-and-select.ll
index b55d917f72..2b0724c7fd 100644
--- a/test/Transforms/SROA/phi-and-select.ll
+++ b/test/Transforms/SROA/phi-and-select.ll
@@ -1,5 +1,5 @@
; RUN: opt < %s -sroa -S | FileCheck %s
-target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
define i32 @test1() {
; CHECK: @test1
@@ -59,15 +59,24 @@ entry:
%a = alloca [2 x i32]
; CHECK-NOT: alloca
+ ; Note that we build redundant GEPs here to ensure that having different GEPs
+ ; into the same alloca partation continues to work with PHI speculation. This
+ ; was the underlying cause of PR13926.
%a0 = getelementptr [2 x i32]* %a, i64 0, i32 0
+ %a0b = getelementptr [2 x i32]* %a, i64 0, i32 0
%a1 = getelementptr [2 x i32]* %a, i64 0, i32 1
+ %a1b = getelementptr [2 x i32]* %a, i64 0, i32 1
store i32 0, i32* %a0
store i32 1, i32* %a1
; CHECK-NOT: store
switch i32 %x, label %bb0 [ i32 1, label %bb1
i32 2, label %bb2
- i32 3, label %bb3 ]
+ i32 3, label %bb3
+ i32 4, label %bb4
+ i32 5, label %bb5
+ i32 6, label %bb6
+ i32 7, label %bb7 ]
bb0:
br label %exit
@@ -77,10 +86,19 @@ bb2:
br label %exit
bb3:
br label %exit
+bb4:
+ br label %exit
+bb5:
+ br label %exit
+bb6:
+ br label %exit
+bb7:
+ br label %exit
exit:
- %phi = phi i32* [ %a1, %bb0 ], [ %a0, %bb1 ], [ %a0, %bb2 ], [ %a1, %bb3 ]
-; CHECK: phi i32 [ 1, %{{.*}} ], [ 0, %{{.*}} ], [ 0, %{{.*}} ], [ 1, %{{.*}} ]
+ %phi = phi i32* [ %a1, %bb0 ], [ %a0, %bb1 ], [ %a0, %bb2 ], [ %a1, %bb3 ],
+ [ %a1b, %bb4 ], [ %a0b, %bb5 ], [ %a0b, %bb6 ], [ %a1b, %bb7 ]
+; CHECK: phi i32 [ 1, %{{.*}} ], [ 0, %{{.*}} ], [ 0, %{{.*}} ], [ 1, %{{.*}} ], [ 1, %{{.*}} ], [ 0, %{{.*}} ], [ 0, %{{.*}} ], [ 1, %{{.*}} ]
%result = load i32* %phi
ret i32 %result
diff --git a/test/Transforms/SROA/vector-promotion.ll b/test/Transforms/SROA/vector-promotion.ll
index 9cbab385c2..80757475a5 100644
--- a/test/Transforms/SROA/vector-promotion.ll
+++ b/test/Transforms/SROA/vector-promotion.ll
@@ -1,5 +1,5 @@
; RUN: opt < %s -sroa -S | FileCheck %s
-target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
%S1 = type { i64, [42 x float] }
diff --git a/test/Transforms/SimplifyCFG/phi-undef-loadstore.ll b/test/Transforms/SimplifyCFG/phi-undef-loadstore.ll
index 65d888ea01..028fb07456 100644
--- a/test/Transforms/SimplifyCFG/phi-undef-loadstore.ll
+++ b/test/Transforms/SimplifyCFG/phi-undef-loadstore.ll
@@ -85,3 +85,31 @@ if.end7: ; preds = %if.else, %if.then4,
; CHECK: if.end7:
; CHECK: phi i32* [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
}
+
+define i32 @test4(i32* %a, i32 %b, i32* %c, i32 %d) nounwind {
+entry:
+ %tobool = icmp eq i32 %b, 0
+ br i1 %tobool, label %if.else, label %if.then
+
+if.then: ; preds = %entry
+ tail call void @bar() nounwind
+ br label %if.end7
+
+if.else: ; preds = %entry
+ %tobool3 = icmp eq i32 %d, 0
+ br i1 %tobool3, label %if.end7, label %if.then4
+
+if.then4: ; preds = %if.else
+ tail call void @bar() nounwind
+ br label %if.end7
+
+if.end7: ; preds = %if.else, %if.then4, %if.then
+ %x.0 = phi i32* [ %a, %if.then ], [ null, %if.then4 ], [ null, %if.else ]
+ %gep = getelementptr i32* %x.0, i32 10
+ %tmp9 = load i32* %gep
+ %tmp10 = or i32 %tmp9, 1
+ store i32 %tmp10, i32* %gep
+ ret i32 %tmp9
+; CHECK: @test4
+; CHECK-NOT: phi
+}
diff --git a/test/Transforms/SimplifyCFG/switch_to_lookup_table.ll b/test/Transforms/SimplifyCFG/switch_to_lookup_table.ll
index 134ac4eeb1..aa48ec6481 100644
--- a/test/Transforms/SimplifyCFG/switch_to_lookup_table.ll
+++ b/test/Transforms/SimplifyCFG/switch_to_lookup_table.ll
@@ -269,3 +269,27 @@ if.end:
; CHECK: switch
; CHECK: phi
}
+
+; PR13985
+define i1 @undef(i32 %tmp) uwtable ssp {
+bb:
+ switch i32 %tmp, label %bb3 [
+ i32 0, label %bb1
+ i32 1, label %bb1
+ i32 7, label %bb2
+ i32 8, label %bb2
+ ]
+
+bb1: ; preds = %bb, %bb
+ br label %bb3
+
+bb2: ; preds = %bb, %bb
+ br label %bb3
+
+bb3: ; preds = %bb2, %bb1, %bb
+ %tmp4 = phi i1 [ undef, %bb ], [ false, %bb2 ], [ true, %bb1 ]
+ ret i1 %tmp4
+; CHECK: define i1 @undef
+; CHECK: %switch.cast = trunc i32 %switch.tableidx to i9
+; CHECK: %switch.downshift = lshr i9 3, %switch.shiftamt
+}
diff --git a/test/lit.cfg b/test/lit.cfg
index 6f44bb3d8c..dc37317ba9 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -139,10 +139,22 @@ if config.test_exec_root is None:
###
+# Provide a target triple for mcjit tests
+mcjit_triple = config.target_triple
+# Force ELF format on Windows
+if re.search(r'cygwin|mingw32|win32', mcjit_triple):
+ mcjit_triple += "-elf"
+config.substitutions.append( ('%mcjit_triple', mcjit_triple) )
+
# When running under valgrind, we mangle '-vg' or '-vg_leak' onto the end of the
# triple so we can check it with XFAIL and XTARGET.
config.target_triple += lit.valgrindTriple
+# Provide a substition for those tests that need to run the jit to obtain data
+# but simply want use the currently considered most reliable jit for platform
+defaultIsMCJIT='true' if 'arm' in config.target_triple else 'false'
+config.substitutions.append( ('%defaultjit', '-use-mcjit='+defaultIsMCJIT) )
+
# Process jit implementation option
jit_impl_cfg = lit.params.get('jit_impl', None)
if jit_impl_cfg == 'mcjit':
diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp
index 888d2c8e92..b40b4f10db 100644
--- a/tools/bugpoint/ExtractFunction.cpp
+++ b/tools/bugpoint/ExtractFunction.cpp
@@ -14,6 +14,7 @@
#include "BugDriver.h"
#include "llvm/Constants.h"
+#include "llvm/DataLayout.h"
#include "llvm/DerivedTypes.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
@@ -25,7 +26,6 @@
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/CodeExtractor.h"
-#include "llvm/Target/TargetData.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileUtilities.h"
diff --git a/tools/bugpoint/OptimizerDriver.cpp b/tools/bugpoint/OptimizerDriver.cpp
index fb090ee176..c56911a32e 100644
--- a/tools/bugpoint/OptimizerDriver.cpp
+++ b/tools/bugpoint/OptimizerDriver.cpp
@@ -16,11 +16,11 @@
//===----------------------------------------------------------------------===//
#include "BugDriver.h"
+#include "llvm/DataLayout.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/Target/TargetData.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/SystemUtils.h"
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
index 125ef7a3ed..c2243243ae 100644
--- a/tools/llc/llc.cpp
+++ b/tools/llc/llc.cpp
@@ -14,6 +14,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/LLVMContext.h"
+#include "llvm/DataLayout.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
@@ -38,7 +39,6 @@
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
-#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Target/TargetMachine.h"
#include <memory>
@@ -677,10 +677,10 @@ int llc_main(int argc, char **argv) {
PM->add(TLI);
// Add the target data from the target machine, if it exists, or the module.
- if (const TargetData *TD = Target.getTargetData())
- PM->add(new TargetData(*TD));
+ if (const DataLayout *TD = Target.getDataLayout())
+ PM->add(new DataLayout(*TD));
else
- PM->add(new TargetData(mod));
+ PM->add(new DataLayout(mod));
// Override default to generate verbose assembly.
Target.setAsmVerbosityDefault(true);
@@ -787,7 +787,7 @@ int llc_main(int argc, char **argv) {
// They may have been eliminated by the StripDeadPrototypes pass,
// or some other pass that is unaware of NeededRecords / IntrinsicLowering.
if (!MetadataTextFilename.empty()) {
- IntrinsicLowering IL(*target->getTargetData());
+ IntrinsicLowering IL(*target->getDataLayout());
IL.AddPrototypes(*M);
int err = WriteTextMetadataFile(*M.get(), TheTriple);
diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp
index c5645ec601..57a31f21b8 100644
--- a/tools/lli/lli.cpp
+++ b/tools/lli/lli.cpp
@@ -338,6 +338,10 @@ void LLIMCJITMemoryManager::invalidateInstructionCache() {
AllocatedCodeMem[i].size());
}
+static int jit_noop() {
+ return 0;
+}
+
void *LLIMCJITMemoryManager::getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure) {
#if defined(__linux__)
@@ -360,6 +364,14 @@ void *LLIMCJITMemoryManager::getPointerToNamedFunction(const std::string &Name,
if (Name == "mknod") return (void*)(intptr_t)&mknod;
#endif // __linux__
+ // We should not invoke parent's ctors/dtors from generated main()!
+ // On Mingw and Cygwin, the symbol __main is resolved to
+ // callee's(eg. tools/lli) one, to invoke wrong duplicated ctors
+ // (and register wrong callee's dtors with atexit(3)).
+ // We expect ExecutionEngine::runStaticConstructorsDestructors()
+ // is called before ExecutionEngine::runFunctionAsMain() is called.
+ if (Name == "__main") return (void*)(intptr_t)&jit_noop;
+
const char *NameStr = Name.c_str();
void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr);
if (Ptr) return Ptr;
diff --git a/tools/llvm-config/Makefile b/tools/llvm-config/Makefile
index e8c86929e1..b20b6bf4a4 100644
--- a/tools/llvm-config/Makefile
+++ b/tools/llvm-config/Makefile
@@ -63,5 +63,5 @@ ifeq ($(LLVM_CROSS_COMPILING),1)
install:: $(DESTDIR)$(PROJ_bindir)
$(Echo) Installing llvm-config-host
$(Verb) $(ProgInstall) $(BuildLLVMToolDir)/llvm-config \
- $(DESTDIR)$(PROJ_bindir)/llvm-config-host
+ $(DESTDIR)$(PROJ_bindir)/$(program_prefix)llvm-config-host
endif
diff --git a/tools/llvm-extract/llvm-extract.cpp b/tools/llvm-extract/llvm-extract.cpp
index 4ea1a9080d..57b546e9a8 100644
--- a/tools/llvm-extract/llvm-extract.cpp
+++ b/tools/llvm-extract/llvm-extract.cpp
@@ -18,7 +18,7 @@
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Transforms/IPO.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h" // @LOCALMOD
#include "llvm/Support/IRReader.h"
@@ -253,7 +253,7 @@ int main(int argc, char **argv) {
// In addition to deleting all other functions, we also want to spiff it
// up a little bit. Do this now.
PassManager Passes;
- Passes.add(new TargetData(M.get())); // Use correct TargetData
+ Passes.add(new DataLayout(M.get())); // Use correct DataLayout
std::vector<GlobalValue*> Gvs(GVs.begin(), GVs.end());
diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp
index 95de8d8a4d..7b5bd0388d 100644
--- a/tools/llvm-rtdyld/llvm-rtdyld.cpp
+++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp
@@ -14,6 +14,8 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
#include "llvm/Object/MachOObject.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
@@ -120,12 +122,14 @@ static int executeInput() {
for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) {
// Load the input memory buffer.
OwningPtr<MemoryBuffer> InputBuffer;
+ OwningPtr<ObjectImage> LoadedObject;
if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFileList[i],
InputBuffer))
return Error("unable to read input: '" + ec.message() + "'");
- // Load the object file into it.
- if (Dyld.loadObject(InputBuffer.take())) {
+ // Load the object file
+ LoadedObject.reset(Dyld.loadObject(new ObjectBuffer(InputBuffer.take())));
+ if (!LoadedObject) {
return Error(Dyld.getErrorString());
}
}
diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp
index 6c4bf49485..effc9c4365 100644
--- a/tools/lto/LTOCodeGenerator.cpp
+++ b/tools/lto/LTOCodeGenerator.cpp
@@ -15,6 +15,7 @@
#include "LTOCodeGenerator.h"
#include "LTOModule.h"
#include "llvm/Constants.h"
+#include "llvm/DataLayout.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Linker.h"
#include "llvm/LLVMContext.h"
@@ -30,7 +31,6 @@
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Transforms/IPO.h"
@@ -441,7 +441,7 @@ void LTOCodeGenerator::applyScopeRestrictions() {
// mark which symbols can not be internalized
MCContext Context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(),NULL);
- Mangler mangler(Context, *_target->getTargetData());
+ Mangler mangler(Context, *_target->getDataLayout());
std::vector<const char*> mustPreserveList;
SmallPtrSet<GlobalValue*, 8> asmUsed;
@@ -509,8 +509,8 @@ bool LTOCodeGenerator::generateObjectFile(raw_ostream &out,
// Start off with a verification pass.
passes.add(createVerifierPass());
- // Add an appropriate TargetData instance for this module...
- passes.add(new TargetData(*_target->getTargetData()));
+ // Add an appropriate DataLayout instance for this module...
+ passes.add(new DataLayout(*_target->getDataLayout()));
// Enabling internalize here would use its AllButMain variant. It
// keeps only main if it exists and does nothing for libraries. Instead
@@ -524,7 +524,7 @@ bool LTOCodeGenerator::generateObjectFile(raw_ostream &out,
FunctionPassManager *codeGenPasses = new FunctionPassManager(mergedModule);
- codeGenPasses->add(new TargetData(*_target->getTargetData()));
+ codeGenPasses->add(new DataLayout(*_target->getDataLayout()));
formatted_raw_ostream Out(out);
diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp
index c3f2ca14dc..c3c6692235 100644
--- a/tools/lto/LTOModule.cpp
+++ b/tools/lto/LTOModule.cpp
@@ -161,7 +161,7 @@ SSPBufferSize("stack-protector-buffer-size", cl::init(8),
LTOModule::LTOModule(llvm::Module *m, llvm::TargetMachine *t)
: _module(m), _target(t),
_context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(), NULL),
- _mangler(_context, *_target->getTargetData()) {}
+ _mangler(_context, *_target->getDataLayout()) {}
/// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM
/// bitcode.
@@ -302,7 +302,7 @@ LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer,
// @LOCALMOD-BEGIN
// Add declarations for functions which may be used by intrinsics.
- IntrinsicLowering IL(*target->getTargetData());
+ IntrinsicLowering IL(*target->getDataLayout());
IL.AddPrototypes(*m);
// @LOCALMOD-END
diff --git a/tools/lto/Makefile b/tools/lto/Makefile
index 7388ef8778..b7e7875a04 100644
--- a/tools/lto/Makefile
+++ b/tools/lto/Makefile
@@ -49,6 +49,14 @@ ifeq ($(HOST_OS),Darwin)
-Wl,-install_name \
-Wl,"@executable_path/../lib/lib$(LIBRARYNAME)$(SHLIBEXT)"
endif
+
+ # If we're doing an Apple-style build, add the LTO object path.
+ ifeq ($(RC_BUILDIT),YES)
+ ObjDir := $(shell mkdir -p ${OBJROOT}/dSYMs)
+ TempFile := $(shell mktemp ${ObjDir}/llvm-lto.XXXXXX)
+ LLVMLibsOptions := $(LLVMLibsOptions) \
+ -Wl,-object_path_lto -Wl,$(TempFile)
+ endif
endif
#@ LOCALMOD-BEGIN
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
index 4a8041d2a0..35ab2d50cb 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/LLVMContext.h"
+#include "llvm/DataLayout.h"
#include "llvm/DebugInfo.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
@@ -23,7 +24,6 @@
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/RegionPass.h"
#include "llvm/Analysis/CallGraph.h"
-#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/StringSet.h"
@@ -569,13 +569,13 @@ int main(int argc, char **argv) {
TLI->disableAllFunctions();
Passes.add(TLI);
- // Add an appropriate TargetData instance for this module.
- TargetData *TD = 0;
+ // Add an appropriate DataLayout instance for this module.
+ DataLayout *TD = 0;
const std::string &ModuleDataLayout = M.get()->getDataLayout();
if (!ModuleDataLayout.empty())
- TD = new TargetData(ModuleDataLayout);
+ TD = new DataLayout(ModuleDataLayout);
else if (!DefaultDataLayout.empty())
- TD = new TargetData(DefaultDataLayout);
+ TD = new DataLayout(DefaultDataLayout);
if (TD)
Passes.add(TD);
@@ -584,7 +584,7 @@ int main(int argc, char **argv) {
if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) {
FPasses.reset(new FunctionPassManager(M.get()));
if (TD)
- FPasses->add(new TargetData(*TD));
+ FPasses->add(new DataLayout(*TD));
}
if (PrintBreakpoints) {
diff --git a/unittests/ADT/StringRefTest.cpp b/unittests/ADT/StringRefTest.cpp
index 315eacbaa4..ead372f365 100644
--- a/unittests/ADT/StringRefTest.cpp
+++ b/unittests/ADT/StringRefTest.cpp
@@ -456,4 +456,27 @@ TEST(StringRefTest, getAsInteger) {
}
}
+
+static const char* BadStrings[] = {
+ "18446744073709551617" // value just over max
+ , "123456789012345678901" // value way too large
+ , "4t23v" // illegal decimal characters
+ , "0x123W56" // illegal hex characters
+ , "0b2" // illegal bin characters
+ , "08" // illegal oct characters
+ , "0o8" // illegal oct characters
+ , "-123" // negative unsigned value
+};
+
+
+TEST(StringRefTest, getAsUnsignedIntegerBadStrings) {
+ unsigned long long U64;
+ for (size_t i = 0; i < array_lengthof(BadStrings); ++i) {
+ bool IsBadNumber = StringRef(BadStrings[i]).getAsInteger(0, U64);
+ ASSERT_TRUE(IsBadNumber);
+ }
+}
+
+
+
} // end anonymous namespace
diff --git a/unittests/ExecutionEngine/CMakeLists.txt b/unittests/ExecutionEngine/CMakeLists.txt
index 5fffadd4ca..ed7f10a23c 100644
--- a/unittests/ExecutionEngine/CMakeLists.txt
+++ b/unittests/ExecutionEngine/CMakeLists.txt
@@ -7,3 +7,4 @@ add_llvm_unittest(ExecutionEngineTests
)
add_subdirectory(JIT)
+add_subdirectory(MCJIT)
diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp
index 89f7e8e422..5e2af030f2 100644
--- a/unittests/ExecutionEngine/JIT/JITTest.cpp
+++ b/unittests/ExecutionEngine/JIT/JITTest.cpp
@@ -224,6 +224,9 @@ class JITTest : public testing::Test {
OwningPtr<ExecutionEngine> TheJIT;
};
+// Tests on ARM disabled as we're running the old jit
+#if !defined(__arm__)
+
// Regression test for a bug. The JIT used to allocate globals inside the same
// memory block used for the function, and when the function code was freed,
// the global was left in the same place. This test allocates a function
@@ -292,6 +295,8 @@ TEST(JIT, GlobalInFunction) {
EXPECT_EQ(3, *GPtr);
}
+#endif // !defined(__arm__)
+
int PlusOne(int arg) {
return arg + 1;
}
@@ -521,6 +526,9 @@ TEST_F(JITTest, NoStubs) {
}
#endif // !ARM && !PPC
+// Tests on ARM disabled as we're running the old jit
+#if !defined(__arm__)
+
TEST_F(JITTest, FunctionPointersOutliveTheirCreator) {
TheJIT->DisableLazyCompilation(true);
LoadAssembly("define i8()* @get_foo_addr() { "
@@ -555,6 +563,8 @@ TEST_F(JITTest, FunctionPointersOutliveTheirCreator) {
#endif
}
+#endif //!defined(__arm__)
+
// ARM does not have an implementation
// of replaceMachineCodeForFunction(), so recompileAndRelinkFunction
// doesn't work.
@@ -599,6 +609,9 @@ extern "C" int32_t JITTest_AvailableExternallyGlobal;
int32_t JITTest_AvailableExternallyGlobal = 42;
namespace {
+// Tests on ARM disabled as we're running the old jit
+#if !defined(__arm__)
+
TEST_F(JITTest, AvailableExternallyGlobalIsntEmitted) {
TheJIT->DisableLazyCompilation(true);
LoadAssembly("@JITTest_AvailableExternallyGlobal = "
@@ -615,7 +628,7 @@ TEST_F(JITTest, AvailableExternallyGlobalIsntEmitted) {
EXPECT_EQ(42, loader()) << "func should return 42 from the external global,"
<< " not 7 from the IR version.";
}
-
+#endif //!defined(__arm__)
} // anonymous namespace
// This function is intentionally defined differently in the statically-compiled
// program from the IR input to the JIT to assert that the JIT doesn't use its
diff --git a/unittests/ExecutionEngine/MCJIT/CMakeLists.txt b/unittests/ExecutionEngine/MCJIT/CMakeLists.txt
new file mode 100644
index 0000000000..3e9c5b631e
--- /dev/null
+++ b/unittests/ExecutionEngine/MCJIT/CMakeLists.txt
@@ -0,0 +1,25 @@
+set(LLVM_LINK_COMPONENTS
+ asmparser
+ bitreader
+ bitwriter
+ mcjit
+ jit
+ nativecodegen
+ )
+
+set(MCJITTestsSources
+ MCJITTest.cpp
+ SectionMemoryManager.cpp
+ )
+
+if(MSVC)
+ list(APPEND MCJITTestsSources MCJITTests.def)
+endif()
+
+add_llvm_unittest(MCJITTests
+ ${MCJITTestsSources}
+ )
+
+if(MINGW OR CYGWIN)
+ set_property(TARGET MCJITTests PROPERTY LINK_FLAGS -Wl,--export-all-symbols)
+endif()
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
new file mode 100644
index 0000000000..4644bf3c26
--- /dev/null
+++ b/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
@@ -0,0 +1,226 @@
+//===- MCJITTest.cpp - Unit tests for the MCJIT ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This test suite verifies basic MCJIT functionality such as making function
+// calls, using global variables, and compiling multpile modules.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/MCJIT.h"
+#include "MCJITTestBase.h"
+#include "SectionMemoryManager.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+class MCJITTest : public testing::Test, public MCJITTestBase {
+protected:
+
+ virtual void SetUp() {
+ M.reset(createEmptyModule("<main>"));
+ }
+};
+
+namespace {
+
+// FIXME: In order to JIT an empty module, there needs to be
+// an interface to ExecutionEngine that forces compilation but
+// does require retrieval of a pointer to a function/global.
+/*
+TEST_F(MCJITTest, empty_module) {
+ createJIT(M.take());
+ //EXPECT_NE(0, TheJIT->getObjectImage())
+ // << "Unable to generate executable loaded object image";
+}
+*/
+
+TEST_F(MCJITTest, global_variable) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ int initialValue = 5;
+ GlobalValue *Global = insertGlobalInt32(M.get(), "test_global", initialValue);
+ createJIT(M.take());
+ void *globalPtr = TheJIT->getPointerToGlobal(Global);
+ EXPECT_TRUE(0 != globalPtr)
+ << "Unable to get pointer to global value from JIT";
+
+ EXPECT_EQ(initialValue, *(int32_t*)globalPtr)
+ << "Unexpected initial value of global";
+}
+
+TEST_F(MCJITTest, add_function) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ Function *F = insertAddFunction(M.get());
+ createJIT(M.take());
+ void *addPtr = TheJIT->getPointerToFunction(F);
+ EXPECT_TRUE(0 != addPtr)
+ << "Unable to get pointer to function from JIT";
+
+ int (*AddPtrTy)(int, int) = (int(*)(int, int))(intptr_t)addPtr;
+ EXPECT_EQ(0, AddPtrTy(0, 0));
+ EXPECT_EQ(3, AddPtrTy(1, 2));
+ EXPECT_EQ(-5, AddPtrTy(-2, -3));
+}
+
+TEST_F(MCJITTest, run_main) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ int rc = 6;
+ Function *Main = insertMainFunction(M.get(), 6);
+ createJIT(M.take());
+ void *vPtr = TheJIT->getPointerToFunction(Main);
+ EXPECT_TRUE(0 != vPtr)
+ << "Unable to get pointer to main() from JIT";
+
+ int (*FuncPtr)(void) = (int(*)(void))(intptr_t)vPtr;
+ int returnCode = FuncPtr();
+ EXPECT_EQ(returnCode, rc);
+}
+
+TEST_F(MCJITTest, return_global) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ int32_t initialNum = 7;
+ GlobalVariable *GV = insertGlobalInt32(M.get(), "myglob", initialNum);
+
+ Function *ReturnGlobal = startFunction<int32_t(void)>(M.get(),
+ "ReturnGlobal");
+ Value *ReadGlobal = Builder.CreateLoad(GV);
+ endFunctionWithRet(ReturnGlobal, ReadGlobal);
+
+ createJIT(M.take());
+ void *rgvPtr = TheJIT->getPointerToFunction(ReturnGlobal);
+ EXPECT_TRUE(0 != rgvPtr);
+
+ int32_t(*FuncPtr)(void) = (int32_t(*)(void))(intptr_t)rgvPtr;
+ EXPECT_EQ(initialNum, FuncPtr())
+ << "Invalid value for global returned from JITted function";
+}
+
+// FIXME: This case fails due to a bug with getPointerToGlobal().
+// The bug is due to MCJIT not having an implementation of getPointerToGlobal()
+// which results in falling back on the ExecutionEngine implementation that
+// allocates a new memory block for the global instead of using the same
+// global variable that is emitted by MCJIT. Hence, the pointer (gvPtr below)
+// has the correct initial value, but updates to the real global (accessed by
+// JITted code) are not propagated. Instead, getPointerToGlobal() should return
+// a pointer into the loaded ObjectImage to reference the emitted global.
+/*
+TEST_F(MCJITTest, increment_global) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ int32_t initialNum = 5;
+ Function *IncrementGlobal = startFunction<int32_t(void)>(M.get(), "IncrementGlobal");
+ GlobalVariable *GV = insertGlobalInt32(M.get(), "my_global", initialNum);
+ Value *DerefGV = Builder.CreateLoad(GV);
+ Value *AddResult = Builder.CreateAdd(DerefGV,
+ ConstantInt::get(Context, APInt(32, 1)));
+ Builder.CreateStore(AddResult, GV);
+ endFunctionWithRet(IncrementGlobal, AddResult);
+
+ createJIT(M.take());
+ void *gvPtr = TheJIT->getPointerToGlobal(GV);
+ EXPECT_EQ(initialNum, *(int32_t*)gvPtr);
+
+ void *vPtr = TheJIT->getPointerToFunction(IncrementGlobal);
+ EXPECT_TRUE(0 != vPtr)
+ << "Unable to get pointer to main() from JIT";
+
+ int32_t(*FuncPtr)(void) = (int32_t(*)(void))(intptr_t)vPtr;
+
+ for(int i = 1; i < 3; ++i) {
+ int32_t result = FuncPtr();
+ EXPECT_EQ(initialNum + i, result); // OK
+ EXPECT_EQ(initialNum + i, *(int32_t*)gvPtr); // FAILS
+ }
+}
+*/
+
+TEST_F(MCJITTest, multiple_functions) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ unsigned int numLevels = 23;
+ int32_t innerRetVal= 5;
+
+ Function *Inner = startFunction<int32_t(void)>(M.get(), "Inner");
+ endFunctionWithRet(Inner, ConstantInt::get(Context, APInt(32, innerRetVal)));
+
+ Function *Outer;
+ for (unsigned int i = 0; i < numLevels; ++i) {
+ std::stringstream funcName;
+ funcName << "level_" << i;
+ Outer = startFunction<int32_t(void)>(M.get(), funcName.str());
+ Value *innerResult = Builder.CreateCall(Inner);
+ endFunctionWithRet(Outer, innerResult);
+
+ Inner = Outer;
+ }
+
+ createJIT(M.take());
+ void *vPtr = TheJIT->getPointerToFunction(Outer);
+ EXPECT_TRUE(0 != vPtr)
+ << "Unable to get pointer to outer function from JIT";
+
+ int32_t(*FuncPtr)(void) = (int32_t(*)(void))(intptr_t)vPtr;
+ EXPECT_EQ(innerRetVal, FuncPtr())
+ << "Incorrect result returned from function";
+}
+
+// FIXME: ExecutionEngine has no support empty modules
+/*
+TEST_F(MCJITTest, multiple_empty_modules) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ createJIT(M.take());
+ // JIT-compile
+ EXPECT_NE(0, TheJIT->getObjectImage())
+ << "Unable to generate executable loaded object image";
+
+ TheJIT->addModule(createEmptyModule("<other module>"));
+ TheJIT->addModule(createEmptyModule("<other other module>"));
+
+ // JIT again
+ EXPECT_NE(0, TheJIT->getObjectImage())
+ << "Unable to generate executable loaded object image";
+}
+*/
+
+// FIXME: MCJIT must support multiple modules
+/*
+TEST_F(MCJITTest, multiple_modules) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ Function *Callee = insertAddFunction(M.get());
+ createJIT(M.take());
+
+ // caller function is defined in a different module
+ M.reset(createEmptyModule("<caller module>"));
+
+ Function *CalleeRef = insertExternalReferenceToFunction(M.get(), Callee);
+ Function *Caller = insertSimpleCallFunction(M.get(), CalleeRef);
+
+ TheJIT->addModule(M.take());
+
+ // get a function pointer in a module that was not used in EE construction
+ void *vPtr = TheJIT->getPointerToFunction(Caller);
+ EXPECT_NE(0, vPtr)
+ << "Unable to get pointer to caller function from JIT";
+
+ int(*FuncPtr)(int, int) = (int(*)(int, int))(intptr_t)vPtr;
+ EXPECT_EQ(0, FuncPtr(0, 0));
+ EXPECT_EQ(30, FuncPtr(10, 20));
+ EXPECT_EQ(-30, FuncPtr(-10, -20));
+
+ // ensure caller is destroyed before callee (free use before def)
+ M.reset();
+}
+*/
+
+}
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
new file mode 100644
index 0000000000..9b4a4ac3cf
--- /dev/null
+++ b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
@@ -0,0 +1,245 @@
+//===- MCJITTestBase.h - Common base class for MCJIT Unit tests ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class implements common functionality required by the MCJIT unit tests,
+// as well as logic to skip tests on unsupported architectures and operating
+// systems.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef MCJIT_TEST_BASE_H
+#define MCJIT_TEST_BASE_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Config/config.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/Function.h"
+#include "llvm/IRBuilder.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/TypeBuilder.h"
+
+#include "SectionMemoryManager.h"
+
+// Used to skip tests on unsupported architectures and operating systems.
+// To skip a test, add this macro at the top of a test-case in a suite that
+// inherits from MCJITTestBase. See MCJITTest.cpp for examples.
+#define SKIP_UNSUPPORTED_PLATFORM \
+ do \
+ if (!ArchSupportsMCJIT() || !OSSupportsMCJIT()) \
+ return; \
+ while(0);
+
+namespace llvm {
+
+class MCJITTestBase {
+protected:
+
+ MCJITTestBase()
+ : OptLevel(CodeGenOpt::None)
+ , RelocModel(Reloc::Default)
+ , CodeModel(CodeModel::Default)
+ , MArch("")
+ , Builder(Context)
+ , MM(new SectionMemoryManager)
+ , HostTriple(LLVM_HOSTTRIPLE)
+ {
+ InitializeNativeTarget();
+ InitializeNativeTargetAsmPrinter();
+
+#ifdef LLVM_ON_WIN32
+ // On Windows, generate ELF objects by specifying "-elf" in triple
+ HostTriple += "-elf";
+#endif // LLVM_ON_WIN32
+ HostTriple = Triple::normalize(HostTriple);
+
+ // The architectures below are known to be compatible with MCJIT as they
+ // are copied from test/ExecutionEngine/MCJIT/lit.local.cfg and should be
+ // kept in sync.
+ SupportedArchs.push_back(Triple::arm);
+ SupportedArchs.push_back(Triple::mips);
+ SupportedArchs.push_back(Triple::x86);
+ SupportedArchs.push_back(Triple::x86_64);
+
+ // The operating systems below are known to be incompatible with MCJIT as
+ // they are copied from the test/ExecutionEngine/MCJIT/lit.local.cfg and
+ // should be kept in sync.
+ UnsupportedOSs.push_back(Triple::Cygwin);
+ UnsupportedOSs.push_back(Triple::Darwin);
+ }
+
+ /// Returns true if the host architecture is known to support MCJIT
+ bool ArchSupportsMCJIT() {
+ Triple Host(HostTriple);
+ if (std::find(SupportedArchs.begin(), SupportedArchs.end(), Host.getArch())
+ == SupportedArchs.end()) {
+ return false;
+ }
+ return true;
+ }
+
+ /// Returns true if the host OS is known to support MCJIT
+ bool OSSupportsMCJIT() {
+ Triple Host(HostTriple);
+ if (std::find(UnsupportedOSs.begin(), UnsupportedOSs.end(), Host.getOS())
+ == UnsupportedOSs.end()) {
+ return true;
+ }
+ return false;
+ }
+
+ Module *createEmptyModule(StringRef Name) {
+ Module * M = new Module(Name, Context);
+ M->setTargetTriple(Triple::normalize(HostTriple));
+ return M;
+ }
+
+ template<typename FuncType>
+ Function *startFunction(Module *M, StringRef Name) {
+ Function *Result = Function::Create(
+ TypeBuilder<FuncType, false>::get(Context),
+ GlobalValue::ExternalLinkage, Name, M);
+
+ BasicBlock *BB = BasicBlock::Create(Context, Name, Result);
+ Builder.SetInsertPoint(BB);
+
+ return Result;
+ }
+
+ void endFunctionWithRet(Function *Func, Value *RetValue) {
+ Builder.CreateRet(RetValue);
+ }
+
+ // Inserts a simple function that invokes Callee and takes the same arguments:
+ // int Caller(...) { return Callee(...); }
+ template<typename Signature>
+ Function *insertSimpleCallFunction(Module *M, Function *Callee) {
+ Function *Result = startFunction<Signature>(M, "caller");
+
+ SmallVector<Value*, 1> CallArgs;
+
+ Function::arg_iterator arg_iter = Result->arg_begin();
+ for(;arg_iter != Result->arg_end(); ++arg_iter)
+ CallArgs.push_back(arg_iter);
+
+ Value *ReturnCode = Builder.CreateCall(Callee, CallArgs);
+ Builder.CreateRet(ReturnCode);
+ return Result;
+ }
+
+ // Inserts a function named 'main' that returns a uint32_t:
+ // int32_t main() { return X; }
+ // where X is given by returnCode
+ Function *insertMainFunction(Module *M, uint32_t returnCode) {
+ Function *Result = startFunction<int32_t(void)>(M, "main");
+
+ Value *ReturnVal = ConstantInt::get(Context, APInt(32, returnCode));
+ endFunctionWithRet(Result, ReturnVal);
+
+ return Result;
+ }
+
+ // Inserts a function
+ // int32_t add(int32_t a, int32_t b) { return a + b; }
+ // in the current module and returns a pointer to it.
+ Function *insertAddFunction(Module *M, StringRef Name = "add") {
+ Function *Result = startFunction<int32_t(int32_t, int32_t)>(M, Name);
+
+ Function::arg_iterator args = Result->arg_begin();
+ Value *Arg1 = args;
+ Value *Arg2 = ++args;
+ Value *AddResult = Builder.CreateAdd(Arg1, Arg2);
+
+ endFunctionWithRet(Result, AddResult);
+
+ return Result;
+ }
+
+ // Inserts an declaration to a function defined elsewhere
+ Function *insertExternalReferenceToFunction(Module *M, StringRef Name,
+ FunctionType *FuncTy) {
+ Function *Result = Function::Create(FuncTy,
+ GlobalValue::ExternalLinkage,
+ Name, M);
+ return Result;
+ }
+
+ // Inserts an declaration to a function defined elsewhere
+ Function *insertExternalReferenceToFunction(Module *M, Function *Func) {
+ Function *Result = Function::Create(Func->getFunctionType(),
+ GlobalValue::AvailableExternallyLinkage,
+ Func->getName(), M);
+ return Result;
+ }
+
+ // Inserts a global variable of type int32
+ GlobalVariable *insertGlobalInt32(Module *M,
+ StringRef name,
+ int32_t InitialValue) {
+ Type *GlobalTy = TypeBuilder<types::i<32>, true>::get(Context);
+ Constant *IV = ConstantInt::get(Context, APInt(32, InitialValue));
+ GlobalVariable *Global = new GlobalVariable(*M,
+ GlobalTy,
+ false,
+ GlobalValue::ExternalLinkage,
+ IV,
+ name);
+ return Global;
+ }
+
+ void createJIT(Module *M) {
+
+ // Due to the EngineBuilder constructor, it is required to have a Module
+ // in order to construct an ExecutionEngine (i.e. MCJIT)
+ assert(M != 0 && "a non-null Module must be provided to create MCJIT");
+
+ EngineBuilder EB(M);
+ std::string Error;
+ TheJIT.reset(EB.setEngineKind(EngineKind::JIT)
+ .setUseMCJIT(true) /* can this be folded into the EngineKind enum? */
+ .setJITMemoryManager(MM)
+ .setErrorStr(&Error)
+ .setOptLevel(CodeGenOpt::None)
+ .setAllocateGVsWithCode(false) /*does this do anything?*/
+ .setCodeModel(CodeModel::JITDefault)
+ .setRelocationModel(Reloc::Default)
+ .setMArch(MArch)
+ .setMCPU(sys::getHostCPUName())
+ //.setMAttrs(MAttrs)
+ .create());
+ // At this point, we cannot modify the module any more.
+ assert(TheJIT.get() != NULL && "error creating MCJIT with EngineBuilder");
+ }
+
+ LLVMContext Context;
+ CodeGenOpt::Level OptLevel;
+ Reloc::Model RelocModel;
+ CodeModel::Model CodeModel;
+ StringRef MArch;
+ SmallVector<std::string, 1> MAttrs;
+ OwningPtr<TargetMachine> TM;
+ OwningPtr<ExecutionEngine> TheJIT;
+ IRBuilder<> Builder;
+ JITMemoryManager *MM;
+
+ std::string HostTriple;
+ SmallVector<Triple::ArchType, 4> SupportedArchs;
+ SmallVector<Triple::OSType, 4> UnsupportedOSs;
+
+ OwningPtr<Module> M;
+};
+
+} // namespace llvm
+
+#endif // MCJIT_TEST_H
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTests.def b/unittests/ExecutionEngine/MCJIT/MCJITTests.def
new file mode 100644
index 0000000000..aabd2247c0
--- /dev/null
+++ b/unittests/ExecutionEngine/MCJIT/MCJITTests.def
@@ -0,0 +1 @@
+EXPORTS
diff --git a/unittests/ExecutionEngine/MCJIT/Makefile b/unittests/ExecutionEngine/MCJIT/Makefile
new file mode 100644
index 0000000000..454f83099d
--- /dev/null
+++ b/unittests/ExecutionEngine/MCJIT/Makefile
@@ -0,0 +1,18 @@
+##===- unittests/ExecutionEngine/MCJIT/Makefile ------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+TESTNAME = MCJIT
+LINK_COMPONENTS := core jit mcjit native support
+
+include $(LEVEL)/Makefile.config
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
+
+# Permit these tests to use the MCJIT's symbolic lookup.
+LD.Flags += $(RDYNAMIC)
diff --git a/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.cpp b/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.cpp
new file mode 100644
index 0000000000..7f3cf2455e
--- /dev/null
+++ b/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.cpp
@@ -0,0 +1,135 @@
+//===-- SectionMemoryManager.cpp - The memory manager for MCJIT -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the implementation of the section-based memory manager
+// used by MCJIT.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Config/config.h"
+#include "llvm/Support/DynamicLibrary.h"
+
+#include "SectionMemoryManager.h"
+
+#ifdef __linux__
+// These includes used by SectionMemoryManager::getPointerToNamedFunction()
+// for Glibc trickery. Look comments in this function for more information.
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <unistd.h>
+#endif
+
+namespace llvm {
+
+uint8_t *SectionMemoryManager::allocateDataSection(uintptr_t Size,
+ unsigned Alignment,
+ unsigned SectionID) {
+ if (!Alignment)
+ Alignment = 16;
+ uint8_t *Addr = (uint8_t*)calloc((Size + Alignment - 1)/Alignment, Alignment);
+ AllocatedDataMem.push_back(sys::MemoryBlock(Addr, Size));
+ return Addr;
+}
+
+uint8_t *SectionMemoryManager::allocateCodeSection(uintptr_t Size,
+ unsigned Alignment,
+ unsigned SectionID) {
+ if (!Alignment)
+ Alignment = 16;
+ unsigned NeedAllocate = Alignment * ((Size + Alignment - 1)/Alignment + 1);
+ uintptr_t Addr = 0;
+ // Look in the list of free code memory regions and use a block there if one
+ // is available.
+ for (int i = 0, e = FreeCodeMem.size(); i != e; ++i) {
+ sys::MemoryBlock &MB = FreeCodeMem[i];
+ if (MB.size() >= NeedAllocate) {
+ Addr = (uintptr_t)MB.base();
+ uintptr_t EndOfBlock = Addr + MB.size();
+ // Align the address.
+ Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1);
+ // Store cutted free memory block.
+ FreeCodeMem[i] = sys::MemoryBlock((void*)(Addr + Size),
+ EndOfBlock - Addr - Size);
+ return (uint8_t*)Addr;
+ }
+ }
+
+ // No pre-allocated free block was large enough. Allocate a new memory region.
+ sys::MemoryBlock MB = sys::Memory::AllocateRWX(NeedAllocate, 0, 0);
+
+ AllocatedCodeMem.push_back(MB);
+ Addr = (uintptr_t)MB.base();
+ uintptr_t EndOfBlock = Addr + MB.size();
+ // Align the address.
+ Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1);
+ // The AllocateRWX may allocate much more memory than we need. In this case,
+ // we store the unused memory as a free memory block.
+ unsigned FreeSize = EndOfBlock-Addr-Size;
+ if (FreeSize > 16)
+ FreeCodeMem.push_back(sys::MemoryBlock((void*)(Addr + Size), FreeSize));
+
+ // Return aligned address
+ return (uint8_t*)Addr;
+}
+
+void SectionMemoryManager::invalidateInstructionCache() {
+ for (int i = 0, e = AllocatedCodeMem.size(); i != e; ++i)
+ sys::Memory::InvalidateInstructionCache(AllocatedCodeMem[i].base(),
+ AllocatedCodeMem[i].size());
+}
+
+void *SectionMemoryManager::getPointerToNamedFunction(const std::string &Name,
+ bool AbortOnFailure) {
+#if defined(__linux__)
+ //===--------------------------------------------------------------------===//
+ // Function stubs that are invoked instead of certain library calls
+ //
+ // Force the following functions to be linked in to anything that uses the
+ // JIT. This is a hack designed to work around the all-too-clever Glibc
+ // strategy of making these functions work differently when inlined vs. when
+ // not inlined, and hiding their real definitions in a separate archive file
+ // that the dynamic linker can't see. For more info, search for
+ // 'libc_nonshared.a' on Google, or read http://llvm.org/PR274.
+ if (Name == "stat") return (void*)(intptr_t)&stat;
+ if (Name == "fstat") return (void*)(intptr_t)&fstat;
+ if (Name == "lstat") return (void*)(intptr_t)&lstat;
+ if (Name == "stat64") return (void*)(intptr_t)&stat64;
+ if (Name == "fstat64") return (void*)(intptr_t)&fstat64;
+ if (Name == "lstat64") return (void*)(intptr_t)&lstat64;
+ if (Name == "atexit") return (void*)(intptr_t)&atexit;
+ if (Name == "mknod") return (void*)(intptr_t)&mknod;
+#endif // __linux__
+
+ const char *NameStr = Name.c_str();
+ void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr);
+ if (Ptr) return Ptr;
+
+ // If it wasn't found and if it starts with an underscore ('_') character,
+ // try again without the underscore.
+ if (NameStr[0] == '_') {
+ Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr+1);
+ if (Ptr) return Ptr;
+ }
+
+ if (AbortOnFailure)
+ report_fatal_error("Program used external function '" + Name +
+ "' which could not be resolved!");
+ return 0;
+}
+
+SectionMemoryManager::~SectionMemoryManager() {
+ for (unsigned i = 0, e = AllocatedCodeMem.size(); i != e; ++i)
+ sys::Memory::ReleaseRWX(AllocatedCodeMem[i]);
+ for (unsigned i = 0, e = AllocatedDataMem.size(); i != e; ++i)
+ free(AllocatedDataMem[i].base());
+}
+
+} // namespace llvm
diff --git a/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h b/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h
new file mode 100644
index 0000000000..fb6c0348b1
--- /dev/null
+++ b/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h
@@ -0,0 +1,117 @@
+//===-- SectionMemoryManager.h - Memory allocator for MCJIT -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of a section-based memory manager used by
+// the MCJIT execution engine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H
+#define LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ExecutionEngine/JITMemoryManager.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Memory.h"
+
+namespace llvm {
+
+// Section-based memory manager for MCJIT
+class SectionMemoryManager : public JITMemoryManager {
+
+public:
+
+ SectionMemoryManager() { }
+ ~SectionMemoryManager();
+
+ virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID);
+
+ virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID);
+
+ virtual void *getPointerToNamedFunction(const std::string &Name,
+ bool AbortOnFailure = true);
+
+ // Invalidate instruction cache for code sections. Some platforms with
+ // separate data cache and instruction cache require explicit cache flush,
+ // otherwise JIT code manipulations (like resolved relocations) will get to
+ // the data cache but not to the instruction cache.
+ virtual void invalidateInstructionCache();
+
+private:
+
+ SmallVector<sys::MemoryBlock, 16> AllocatedDataMem;
+ SmallVector<sys::MemoryBlock, 16> AllocatedCodeMem;
+ SmallVector<sys::MemoryBlock, 16> FreeCodeMem;
+
+public:
+ ///
+ /// Functions below are not used by MCJIT, but must be implemented because
+ /// they are declared as pure virtuals in the base class.
+ ///
+
+ virtual void setMemoryWritable() {
+ llvm_unreachable("Unexpected call!");
+ }
+ virtual void setMemoryExecutable() {
+ llvm_unreachable("Unexpected call!");
+ }
+ virtual void setPoisonMemory(bool poison) {
+ llvm_unreachable("Unexpected call!");
+ }
+ virtual void AllocateGOT() {
+ llvm_unreachable("Unexpected call!");
+ }
+ virtual uint8_t *getGOTBase() const {
+ llvm_unreachable("Unexpected call!");
+ return 0;
+ }
+ virtual uint8_t *startFunctionBody(const Function *F,
+ uintptr_t &ActualSize){
+ llvm_unreachable("Unexpected call!");
+ return 0;
+ }
+ virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
+ unsigned Alignment) {
+ llvm_unreachable("Unexpected call!");
+ return 0;
+ }
+ virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
+ uint8_t *FunctionEnd) {
+ llvm_unreachable("Unexpected call!");
+ }
+ virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
+ llvm_unreachable("Unexpected call!");
+ return 0;
+ }
+ virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
+ llvm_unreachable("Unexpected call!");
+ return 0;
+ }
+ virtual void deallocateFunctionBody(void *Body) {
+ llvm_unreachable("Unexpected call!");
+ }
+ virtual uint8_t *startExceptionTable(const Function *F,
+ uintptr_t &ActualSize) {
+ llvm_unreachable("Unexpected call!");
+ return 0;
+ }
+ virtual void endExceptionTable(const Function *F, uint8_t *TableStart,
+ uint8_t *TableEnd, uint8_t *FrameRegister) {
+ llvm_unreachable("Unexpected call!");
+ }
+ virtual void deallocateExceptionTable(void *ET) {
+ llvm_unreachable("Unexpected call!");
+ }
+};
+
+}
+
+#endif // LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H
diff --git a/unittests/ExecutionEngine/Makefile b/unittests/ExecutionEngine/Makefile
index 63508d2399..ca1195631a 100644
--- a/unittests/ExecutionEngine/Makefile
+++ b/unittests/ExecutionEngine/Makefile
@@ -10,7 +10,7 @@
LEVEL = ../..
TESTNAME = ExecutionEngine
LINK_COMPONENTS :=interpreter
-PARALLEL_DIRS = JIT
+PARALLEL_DIRS = JIT MCJIT
include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/Support/CMakeLists.txt b/unittests/Support/CMakeLists.txt
index e562fbb18d..09a0ea50d7 100644
--- a/unittests/Support/CMakeLists.txt
+++ b/unittests/Support/CMakeLists.txt
@@ -17,6 +17,7 @@ add_llvm_unittest(SupportTests
LeakDetectorTest.cpp
ManagedStatic.cpp
MathExtrasTest.cpp
+ MemoryBufferTest.cpp
MemoryTest.cpp
Path.cpp
RegexTest.cpp
diff --git a/unittests/Support/MemoryBufferTest.cpp b/unittests/Support/MemoryBufferTest.cpp
new file mode 100644
index 0000000000..6c78cd80e8
--- /dev/null
+++ b/unittests/Support/MemoryBufferTest.cpp
@@ -0,0 +1,99 @@
+//===- llvm/unittest/Support/MemoryBufferTest.cpp - MemoryBuffer tests ----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements unit tests for the MemoryBuffer support class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/ADT/OwningPtr.h"
+
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+class MemoryBufferTest : public testing::Test {
+protected:
+ MemoryBufferTest()
+ : data("this is some data")
+ { }
+
+ virtual void SetUp() { }
+
+ typedef OwningPtr<MemoryBuffer> OwningBuffer;
+
+ std::string data;
+};
+
+namespace {
+
+TEST_F(MemoryBufferTest, get) {
+ // Default name and null-terminator flag
+ OwningBuffer MB1(MemoryBuffer::getMemBuffer(data));
+ EXPECT_TRUE(0 != MB1.get());
+
+ // RequiresNullTerminator = false
+ OwningBuffer MB2(MemoryBuffer::getMemBuffer(data, "one", false));
+ EXPECT_TRUE(0 != MB2.get());
+
+ // RequiresNullTerminator = true
+ OwningBuffer MB3(MemoryBuffer::getMemBuffer(data, "two", true));
+ EXPECT_TRUE(0 != MB3.get());
+
+ // verify all 3 buffers point to the same address
+ EXPECT_EQ(MB1->getBufferStart(), MB2->getBufferStart());
+ EXPECT_EQ(MB2->getBufferStart(), MB3->getBufferStart());
+
+ // verify the original data is unmodified after deleting the buffers
+ MB1.reset();
+ MB2.reset();
+ MB3.reset();
+ EXPECT_EQ("this is some data", data);
+}
+
+TEST_F(MemoryBufferTest, copy) {
+ // copy with no name
+ OwningBuffer MBC1(MemoryBuffer::getMemBufferCopy(data));
+ EXPECT_TRUE(0 != MBC1.get());
+
+ // copy with a name
+ OwningBuffer MBC2(MemoryBuffer::getMemBufferCopy(data, "copy"));
+ EXPECT_TRUE(0 != MBC2.get());
+
+ // verify the two copies do not point to the same place
+ EXPECT_NE(MBC1->getBufferStart(), MBC2->getBufferStart());
+}
+
+TEST_F(MemoryBufferTest, make_new) {
+ // 0-sized buffer
+ OwningBuffer Zero(MemoryBuffer::getNewUninitMemBuffer(0));
+ EXPECT_TRUE(0 != Zero.get());
+
+ // uninitialized buffer with no name
+ OwningBuffer One(MemoryBuffer::getNewUninitMemBuffer(321));
+ EXPECT_TRUE(0 != One.get());
+
+ // uninitialized buffer with name
+ OwningBuffer Two(MemoryBuffer::getNewUninitMemBuffer(123, "bla"));
+ EXPECT_TRUE(0 != Two.get());
+
+ // 0-initialized buffer with no name
+ OwningBuffer Three(MemoryBuffer::getNewMemBuffer(321, data));
+ EXPECT_TRUE(0 != Three.get());
+ for (size_t i = 0; i < 321; ++i)
+ EXPECT_EQ(0, Three->getBufferStart()[0]);
+
+ // 0-initialized buffer with name
+ OwningBuffer Four(MemoryBuffer::getNewMemBuffer(123, "zeros"));
+ EXPECT_TRUE(0 != Four.get());
+ for (size_t i = 0; i < 123; ++i)
+ EXPECT_EQ(0, Four->getBufferStart()[0]);
+}
+
+}
diff --git a/unittests/VMCore/InstructionsTest.cpp b/unittests/VMCore/InstructionsTest.cpp
index 72cdc8b994..4cadc36f8f 100644
--- a/unittests/VMCore/InstructionsTest.cpp
+++ b/unittests/VMCore/InstructionsTest.cpp
@@ -9,6 +9,7 @@
#include "llvm/BasicBlock.h"
#include "llvm/Constants.h"
+#include "llvm/DataLayout.h"
#include "llvm/DerivedTypes.h"
#include "llvm/IRBuilder.h"
#include "llvm/Instructions.h"
@@ -17,7 +18,6 @@
#include "llvm/Operator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/Target/TargetData.h"
#include "gtest/gtest.h"
namespace llvm {
@@ -183,7 +183,7 @@ TEST(InstructionsTest, VectorGep) {
EXPECT_NE(S3, Gep3);
int64_t Offset;
- TargetData TD("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3"
+ DataLayout TD("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3"
"2:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80"
":128:128-n8:16:32:64-S128");
// Make sure we don't crash
diff --git a/unittests/VMCore/PassManagerTest.cpp b/unittests/VMCore/PassManagerTest.cpp
index 60d33c19c3..9c070c84bb 100644
--- a/unittests/VMCore/PassManagerTest.cpp
+++ b/unittests/VMCore/PassManagerTest.cpp
@@ -14,7 +14,7 @@
#include "llvm/Pass.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/CallGraphSCCPass.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/DataLayout.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
@@ -94,7 +94,7 @@ namespace llvm {
initializeModuleNDMPass(*PassRegistry::getPassRegistry());
}
virtual bool runOnModule(Module &M) {
- EXPECT_TRUE(getAnalysisIfAvailable<TargetData>());
+ EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
run++;
return false;
}
@@ -167,7 +167,7 @@ namespace llvm {
initializeCGPassPass(*PassRegistry::getPassRegistry());
}
virtual bool runOnSCC(CallGraphSCC &SCMM) {
- EXPECT_TRUE(getAnalysisIfAvailable<TargetData>());
+ EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
run();
return false;
}
@@ -177,7 +177,7 @@ namespace llvm {
public:
virtual bool runOnFunction(Function &F) {
// FIXME: PR4112
- // EXPECT_TRUE(getAnalysisIfAvailable<TargetData>());
+ // EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
run();
return false;
}
@@ -204,7 +204,7 @@ namespace llvm {
return false;
}
virtual bool runOnLoop(Loop *L, LPPassManager &LPM) {
- EXPECT_TRUE(getAnalysisIfAvailable<TargetData>());
+ EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
run();
return false;
}
@@ -241,7 +241,7 @@ namespace llvm {
return false;
}
virtual bool runOnBasicBlock(BasicBlock &BB) {
- EXPECT_TRUE(getAnalysisIfAvailable<TargetData>());
+ EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
run();
return false;
}
@@ -266,7 +266,7 @@ namespace llvm {
initializeFPassPass(*PassRegistry::getPassRegistry());
}
virtual bool runOnModule(Module &M) {
- EXPECT_TRUE(getAnalysisIfAvailable<TargetData>());
+ EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
for (Module::iterator I=M.begin(),E=M.end(); I != E; ++I) {
Function &F = *I;
{
@@ -292,7 +292,7 @@ namespace llvm {
mNDM->run = mNDNM->run = mDNM->run = mNDM2->run = 0;
PassManager Passes;
- Passes.add(new TargetData(&M));
+ Passes.add(new DataLayout(&M));
Passes.add(mNDM2);
Passes.add(mNDM);
Passes.add(mNDNM);
@@ -316,7 +316,7 @@ namespace llvm {
mNDM->run = mNDNM->run = mDNM->run = mNDM2->run = 0;
PassManager Passes;
- Passes.add(new TargetData(&M));
+ Passes.add(new DataLayout(&M));
Passes.add(mNDM);
Passes.add(mNDNM);
Passes.add(mNDM2);// invalidates mNDM needed by mDNM
@@ -338,7 +338,7 @@ namespace llvm {
OwningPtr<Module> M(makeLLVMModule());
T *P = new T();
PassManager Passes;
- Passes.add(new TargetData(M.get()));
+ Passes.add(new DataLayout(M.get()));
Passes.add(P);
Passes.run(*M);
T::finishedOK(run);
@@ -349,7 +349,7 @@ namespace llvm {
Module *M = makeLLVMModule();
T *P = new T();
PassManager Passes;
- Passes.add(new TargetData(M));
+ Passes.add(new DataLayout(M));
Passes.add(P);
Passes.run(*M);
T::finishedOK(run, N);
@@ -387,7 +387,7 @@ namespace llvm {
SCOPED_TRACE("Running OnTheFlyTest");
struct OnTheFlyTest *O = new OnTheFlyTest();
PassManager Passes;
- Passes.add(new TargetData(M));
+ Passes.add(new DataLayout(M));
Passes.add(O);
Passes.run(*M);
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp
index 7b49723d21..435baeef0c 100644
--- a/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/utils/TableGen/AsmMatcherEmitter.cpp
@@ -1674,9 +1674,9 @@ static unsigned getConverterOperandID(const std::string &Name,
}
-static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
- std::vector<MatchableInfo*> &Infos,
- raw_ostream &OS) {
+static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
+ std::vector<MatchableInfo*> &Infos,
+ raw_ostream &OS) {
SetVector<std::string> OperandConversionKinds;
SetVector<std::string> InstructionConversionKinds;
std::vector<std::vector<uint8_t> > ConversionTable;
@@ -1713,29 +1713,23 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
std::string OperandFnBody;
raw_string_ostream OpOS(OperandFnBody);
// Start the operand number lookup function.
- OpOS << "unsigned " << Target.getName() << ClassName << "::\n"
- << "getMCInstOperandNum(unsigned Kind,\n"
- << " const SmallVectorImpl<MCParsedAsmOperand*> "
- << "&Operands,\n unsigned OperandNum, unsigned "
- << "&NumMCOperands) {\n"
+ OpOS << "void " << Target.getName() << ClassName << "::\n"
+ << "convertToMapAndConstraints(unsigned Kind,\n";
+ OpOS.indent(27);
+ OpOS << "const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n";
+ OpOS.indent(27);
+ OpOS << "MatchInstMapAndConstraintsImpl &MapAndConstraints) {\n"
<< " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"
- << " NumMCOperands = 0;\n"
- << " unsigned MCOperandNum = 0;\n"
+ << " unsigned NumMCOperands = 0;\n"
<< " const uint8_t *Converter = ConversionTable[Kind];\n"
<< " for (const uint8_t *p = Converter; *p; p+= 2) {\n"
- << " if (*(p + 1) > OperandNum) continue;\n"
<< " switch (*p) {\n"
<< " default: llvm_unreachable(\"invalid conversion entry!\");\n"
<< " case CVT_Reg:\n"
- << " if (*(p + 1) == OperandNum) {\n"
- << " NumMCOperands = 1;\n"
- << " break;\n"
- << " }\n"
- << " ++MCOperandNum;\n"
- << " break;\n"
<< " case CVT_Tied:\n"
- << " // FIXME: Tied operand calculation not supported.\n"
- << " assert (0 && \"getMCInstOperandNumImpl() doesn't support tied operands, yet!\");\n"
+ << " MapAndConstraints.push_back(std::make_pair(NumMCOperands,"
+ << "\"m\"));\n"
+ << " ++NumMCOperands;\n"
<< " break;\n";
// Pre-populate the operand conversion kinds with the standard always
@@ -1831,11 +1825,9 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
// Add a handler for the operand number lookup.
OpOS << " case " << Name << ":\n"
- << " if (*(p + 1) == OperandNum) {\n"
- << " NumMCOperands = " << OpInfo.MINumOperands << ";\n"
- << " break;\n"
- << " }\n"
- << " MCOperandNum += " << OpInfo.MINumOperands << ";\n"
+ << " MapAndConstraints.push_back(std::make_pair(NumMCOperands"
+ << ",\"m\"));\n"
+ << " NumMCOperands += " << OpInfo.MINumOperands << ";\n"
<< " break;\n";
break;
}
@@ -1872,11 +1864,9 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
<< " break;\n";
OpOS << " case " << Name << ":\n"
- << " if (*(p + 1) == OperandNum) {\n"
- << " NumMCOperands = 1;\n"
- << " break;\n"
- << " }\n"
- << " ++MCOperandNum;\n"
+ << " MapAndConstraints.push_back(std::make_pair(NumMCOperands"
+ << ",\"\"));\n"
+ << " ++NumMCOperands;\n"
<< " break;\n";
break;
}
@@ -1905,11 +1895,9 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
<< " break;\n";
OpOS << " case " << Name << ":\n"
- << " if (*(p + 1) == OperandNum) {\n"
- << " NumMCOperands = 1;\n"
- << " break;\n"
- << " }\n"
- << " ++MCOperandNum;\n"
+ << " MapAndConstraints.push_back(std::make_pair(NumMCOperands"
+ << ",\"m\"));\n"
+ << " ++NumMCOperands;\n"
<< " break;\n";
}
}
@@ -1934,7 +1922,7 @@ static void emitConvertToMCInst(CodeGenTarget &Target, StringRef ClassName,
CvtOS << " }\n }\n}\n\n";
// Finish up the operand number lookup function.
- OpOS << " }\n }\n return MCOperandNum;\n}\n\n";
+ OpOS << " }\n }\n}\n\n";
OS << "namespace {\n";
@@ -2615,17 +2603,22 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " unsigned ComputeAvailableFeatures(uint64_t FeatureBits) const;\n";
OS << " void convertToMCInst(unsigned Kind, MCInst &Inst, "
<< "unsigned Opcode,\n"
- << " const SmallVectorImpl<MCParsedAsmOperand*> "
+ << " const SmallVectorImpl<MCParsedAsmOperand*> "
<< "&Operands);\n";
- OS << " unsigned getMCInstOperandNum(unsigned Kind,\n"
- << " const "
- << "SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n "
- << " unsigned OperandNum, unsigned &NumMCOperands);\n";
+ OS << " void convertToMapAndConstraints(unsigned Kind,\n ";
+ OS << " const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n";
+ OS.indent(29);
+ OS << "MatchInstMapAndConstraintsImpl &MapAndConstraints);\n";
OS << " bool mnemonicIsValid(StringRef Mnemonic);\n";
- OS << " unsigned MatchInstructionImpl(\n"
- << " const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"
- << " unsigned &Kind, MCInst &Inst, "
- << "unsigned &ErrorInfo,\n unsigned VariantID = 0);\n";
+ OS << " unsigned MatchInstructionImpl(\n";
+ OS.indent(27);
+ OS << "const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"
+ << " unsigned &Kind, MCInst &Inst,\n";
+ OS.indent(30);
+ OS << "MatchInstMapAndConstraintsImpl &MapAndConstraints,\n"
+ << " unsigned &ErrorInfo,"
+ << " bool matchingInlineAsm,\n"
+ << " unsigned VariantID = 0);\n";
if (Info.OperandMatchInfo.size()) {
OS << "\n enum OperandMatchResultTy {\n";
@@ -2678,8 +2671,10 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
// Generate the function that remaps for mnemonic aliases.
bool HasMnemonicAliases = emitMnemonicAliases(OS, Info);
- // Generate the unified function to convert operands into an MCInst.
- emitConvertToMCInst(Target, ClassName, Info.Matchables, OS);
+ // Generate the convertToMCInst function to convert operands into an MCInst.
+ // Also, generate the convertToMapAndConstraints function for MS-style inline
+ // assembly. The latter doesn't actually generate a MCInst.
+ emitConvertFuncs(Target, ClassName, Info.Matchables, OS);
// Emit the enumeration for classes which participate in matching.
emitMatchClassEnumeration(Target, Info.Classes, OS);
@@ -2813,8 +2808,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
<< Target.getName() << ClassName << "::\n"
<< "MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>"
<< " &Operands,\n";
- OS << " unsigned &Kind, MCInst &Inst, unsigned ";
- OS << "&ErrorInfo,\n unsigned VariantID) {\n";
+ OS << " unsigned &Kind, MCInst &Inst,\n"
+ << "SmallVectorImpl<std::pair< unsigned, std::string > > &MapAndConstraints,\n"
+ << "unsigned &ErrorInfo, bool matchingInlineAsm, unsigned VariantID) {\n";
OS << " // Eliminate obvious mismatches.\n";
OS << " if (Operands.size() > " << (MaxNumOperands+1) << ") {\n";
@@ -2908,6 +2904,13 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " continue;\n";
OS << " }\n";
OS << "\n";
+ OS << " if (matchingInlineAsm) {\n";
+ OS << " Kind = it->ConvertFn;\n";
+ OS << " Inst.setOpcode(it->Opcode);\n";
+ OS << " convertToMapAndConstraints(it->ConvertFn, Operands, "
+ << "MapAndConstraints);\n";
+ OS << " return Match_Success;\n";
+ OS << " }\n\n";
OS << " // We have selected a definite instruction, convert the parsed\n"
<< " // operands into the appropriate MCInst.\n";
OS << " convertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n";
@@ -2931,7 +2934,6 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
if (!InsnCleanupFn.empty())
OS << " " << InsnCleanupFn << "(Inst);\n";
- OS << " Kind = it->ConvertFn;\n";
OS << " return Match_Success;\n";
OS << " }\n\n";
diff --git a/utils/TableGen/CallingConvEmitter.cpp b/utils/TableGen/CallingConvEmitter.cpp
index e9c4bd30f9..dff97f4e83 100644
--- a/utils/TableGen/CallingConvEmitter.cpp
+++ b/utils/TableGen/CallingConvEmitter.cpp
@@ -177,12 +177,12 @@ void CallingConvEmitter::EmitAction(Record *Action,
if (Size)
O << Size << ", ";
else
- O << "\n" << IndentStr << " State.getTarget().getTargetData()"
+ O << "\n" << IndentStr << " State.getTarget().getDataLayout()"
"->getTypeAllocSize(EVT(LocVT).getTypeForEVT(State.getContext())), ";
if (Align)
O << Align;
else
- O << "\n" << IndentStr << " State.getTarget().getTargetData()"
+ O << "\n" << IndentStr << " State.getTarget().getDataLayout()"
"->getABITypeAlignment(EVT(LocVT).getTypeForEVT(State.getContext()))";
if (Action->isSubClassOf("CCAssignToStackWithShadow"))
O << ", " << getQualifiedName(Action->getValueAsDef("ShadowReg"));
diff --git a/utils/TableGen/CodeGenSchedule.cpp b/utils/TableGen/CodeGenSchedule.cpp
index e54202e3f2..b9b1c293f0 100644
--- a/utils/TableGen/CodeGenSchedule.cpp
+++ b/utils/TableGen/CodeGenSchedule.cpp
@@ -18,6 +18,8 @@
#include "CodeGenTarget.h"
#include "llvm/TableGen/Error.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/ADT/STLExtras.h"
using namespace llvm;
@@ -34,11 +36,64 @@ static void dumpIdxVec(const SmallVectorImpl<unsigned> &V) {
}
#endif
+// (instrs a, b, ...) Evaluate and union all arguments. Identical to AddOp.
+struct InstrsOp : public SetTheory::Operator {
+ void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts) {
+ ST.evaluate(Expr->arg_begin(), Expr->arg_end(), Elts);
+ }
+};
+
+// (instregex "OpcPat",...) Find all instructions matching an opcode pattern.
+//
+// TODO: Since this is a prefix match, perform a binary search over the
+// instruction names using lower_bound. Note that the predefined instrs must be
+// scanned linearly first. However, this is only safe if the regex pattern has
+// no top-level bars. The DAG already has a list of patterns, so there's no
+// reason to use top-level bars, but we need a way to verify they don't exist
+// before implementing the optimization.
+struct InstRegexOp : public SetTheory::Operator {
+ const CodeGenTarget &Target;
+ InstRegexOp(const CodeGenTarget &t): Target(t) {}
+
+ void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts) {
+ SmallVector<Regex*, 4> RegexList;
+ for (DagInit::const_arg_iterator
+ AI = Expr->arg_begin(), AE = Expr->arg_end(); AI != AE; ++AI) {
+ StringInit *SI = dynamic_cast<StringInit*>(*AI);
+ if (!SI)
+ throw "instregex requires pattern string: " + Expr->getAsString();
+ std::string pat = SI->getValue();
+ // Implement a python-style prefix match.
+ if (pat[0] != '^') {
+ pat.insert(0, "^(");
+ pat.insert(pat.end(), ')');
+ }
+ RegexList.push_back(new Regex(pat));
+ }
+ for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
+ E = Target.inst_end(); I != E; ++I) {
+ for (SmallVectorImpl<Regex*>::iterator
+ RI = RegexList.begin(), RE = RegexList.end(); RI != RE; ++RI) {
+ if ((*RI)->match((*I)->TheDef->getName()))
+ Elts.insert((*I)->TheDef);
+ }
+ }
+ DeleteContainerPointers(RegexList);
+ }
+};
+
/// CodeGenModels ctor interprets machine model records and populates maps.
CodeGenSchedModels::CodeGenSchedModels(RecordKeeper &RK,
const CodeGenTarget &TGT):
Records(RK), Target(TGT), NumItineraryClasses(0) {
+ Sets.addFieldExpander("InstRW", "Instrs");
+
+ // Allow Set evaluation to recognize the dags used in InstRW records:
+ // (instrs Op1, Op1...)
+ Sets.addOperator("instrs", new InstrsOp);
+ Sets.addOperator("instregex", new InstRegexOp(Target));
+
// Instantiate a CodeGenProcModel for each SchedMachineModel with the values
// that are explicitly referenced in tablegen records. Resources associated
// with each processor will be derived later. Populate ProcModelMap with the
@@ -72,9 +127,6 @@ CodeGenSchedModels::CodeGenSchedModels(RecordKeeper &RK,
// Infer new SchedClasses from SchedVariant.
inferSchedClasses();
- DEBUG(for (unsigned i = 0; i < SchedClasses.size(); ++i)
- SchedClasses[i].dump(this));
-
// Populate each CodeGenProcModel's WriteResDefs, ReadAdvanceDefs, and
// ProcResourceDefs.
collectProcResources();
@@ -228,12 +280,12 @@ void CodeGenSchedModels::collectSchedRW() {
std::sort(SWDefs.begin(), SWDefs.end(), LessRecord());
for (RecIter SWI = SWDefs.begin(), SWE = SWDefs.end(); SWI != SWE; ++SWI) {
assert(!getSchedRWIdx(*SWI, /*IsRead=*/false) && "duplicate SchedWrite");
- SchedWrites.push_back(CodeGenSchedRW(*SWI));
+ SchedWrites.push_back(CodeGenSchedRW(SchedWrites.size(), *SWI));
}
std::sort(SRDefs.begin(), SRDefs.end(), LessRecord());
for (RecIter SRI = SRDefs.begin(), SRE = SRDefs.end(); SRI != SRE; ++SRI) {
assert(!getSchedRWIdx(*SRI, /*IsRead-*/true) && "duplicate SchedWrite");
- SchedReads.push_back(CodeGenSchedRW(*SRI));
+ SchedReads.push_back(CodeGenSchedRW(SchedReads.size(), *SRI));
}
// Initialize WriteSequence vectors.
for (std::vector<CodeGenSchedRW>::iterator WI = SchedWrites.begin(),
@@ -365,6 +417,47 @@ void CodeGenSchedModels::expandRWSequence(unsigned RWIdx, IdxVec &RWSeq,
}
}
+// Expand a SchedWrite as a sequence following any aliases that coincide with
+// the given processor model.
+void CodeGenSchedModels::expandRWSeqForProc(
+ unsigned RWIdx, IdxVec &RWSeq, bool IsRead,
+ const CodeGenProcModel &ProcModel) const {
+
+ const CodeGenSchedRW &SchedWrite = getSchedRW(RWIdx, IsRead);
+ Record *AliasDef = 0;
+ for (RecIter AI = SchedWrite.Aliases.begin(), AE = SchedWrite.Aliases.end();
+ AI != AE; ++AI) {
+ const CodeGenSchedRW &AliasRW = getSchedRW((*AI)->getValueAsDef("AliasRW"));
+ if ((*AI)->getValueInit("SchedModel")->isComplete()) {
+ Record *ModelDef = (*AI)->getValueAsDef("SchedModel");
+ if (&getProcModel(ModelDef) != &ProcModel)
+ continue;
+ }
+ if (AliasDef)
+ throw TGError(AliasRW.TheDef->getLoc(), "Multiple aliases "
+ "defined for processor " + ProcModel.ModelName +
+ " Ensure only one SchedAlias exists per RW.");
+ AliasDef = AliasRW.TheDef;
+ }
+ if (AliasDef) {
+ expandRWSeqForProc(getSchedRWIdx(AliasDef, IsRead),
+ RWSeq, IsRead,ProcModel);
+ return;
+ }
+ if (!SchedWrite.IsSequence) {
+ RWSeq.push_back(RWIdx);
+ return;
+ }
+ int Repeat =
+ SchedWrite.TheDef ? SchedWrite.TheDef->getValueAsInt("Repeat") : 1;
+ for (int i = 0; i < Repeat; ++i) {
+ for (IdxIter I = SchedWrite.Sequence.begin(), E = SchedWrite.Sequence.end();
+ I != E; ++I) {
+ expandRWSeqForProc(*I, RWSeq, IsRead, ProcModel);
+ }
+ }
+}
+
// Find the existing SchedWrite that models this sequence of writes.
unsigned CodeGenSchedModels::findRWForSequence(const IdxVec &Seq,
bool IsRead) {
@@ -390,13 +483,13 @@ unsigned CodeGenSchedModels::findOrInsertRW(ArrayRef<unsigned> Seq,
if (Idx)
return Idx;
- CodeGenSchedRW SchedRW(Seq, genRWName(Seq, IsRead));
- if (IsRead) {
+ unsigned RWIdx = IsRead ? SchedReads.size() : SchedWrites.size();
+ CodeGenSchedRW SchedRW(RWIdx, IsRead, Seq, genRWName(Seq, IsRead));
+ if (IsRead)
SchedReads.push_back(SchedRW);
- return SchedReads.size() - 1;
- }
- SchedWrites.push_back(SchedRW);
- return SchedWrites.size() - 1;
+ else
+ SchedWrites.push_back(SchedRW);
+ return RWIdx;
}
/// Visit all the instruction definitions for this target to gather and
@@ -475,7 +568,7 @@ void CodeGenSchedModels::collectSchedClasses() {
RWI != RWE; ++RWI) {
const CodeGenProcModel &ProcModel =
getProcModel((*RWI)->getValueAsDef("SchedModel"));
- dbgs() << "InstrRW on " << ProcModel.ModelName << " for " << InstName;
+ dbgs() << "InstRW on " << ProcModel.ModelName << " for " << InstName;
IdxVec Writes;
IdxVec Reads;
findRWs((*RWI)->getValueAsListOfDefs("OperandReadWrites"),
@@ -608,9 +701,11 @@ void CodeGenSchedModels::createInstRWClass(Record *InstRWDef) {
// determined from ItinDef or SchedRW.
SmallVector<std::pair<unsigned, SmallVector<Record *, 8> >, 4> ClassInstrs;
// Sort Instrs into sets.
- RecVec InstDefs = InstRWDef->getValueAsListOfDefs("Instrs");
- std::sort(InstDefs.begin(), InstDefs.end(), LessRecord());
- for (RecIter I = InstDefs.begin(), E = InstDefs.end(); I != E; ++I) {
+ const RecVec *InstDefs = Sets.expand(InstRWDef);
+ if (InstDefs->empty())
+ throw TGError(InstRWDef->getLoc(), "No matching instruction opcodes");
+
+ for (RecIter I = InstDefs->begin(), E = InstDefs->end(); I != E; ++I) {
unsigned SCIdx = 0;
InstClassMapTy::const_iterator Pos = InstrClassMap.find(*I);
if (Pos != InstrClassMap.end())
@@ -659,13 +754,22 @@ void CodeGenSchedModels::createInstRWClass(Record *InstRWDef) {
SC.ProcIndices.push_back(0);
// Map each Instr to this new class.
// Note that InstDefs may be a smaller list than InstRWDef's "Instrs".
+ Record *RWModelDef = InstRWDef->getValueAsDef("SchedModel");
+ SmallSet<unsigned, 4> RemappedClassIDs;
for (ArrayRef<Record*>::const_iterator
II = InstDefs.begin(), IE = InstDefs.end(); II != IE; ++II) {
unsigned OldSCIdx = InstrClassMap[*II];
- if (OldSCIdx) {
- SC.InstRWs.insert(SC.InstRWs.end(),
- SchedClasses[OldSCIdx].InstRWs.begin(),
- SchedClasses[OldSCIdx].InstRWs.end());
+ if (OldSCIdx && RemappedClassIDs.insert(OldSCIdx)) {
+ for (RecIter RI = SchedClasses[OldSCIdx].InstRWs.begin(),
+ RE = SchedClasses[OldSCIdx].InstRWs.end(); RI != RE; ++RI) {
+ if ((*RI)->getValueAsDef("SchedModel") == RWModelDef) {
+ throw TGError(InstRWDef->getLoc(), "Overlapping InstRW def " +
+ (*II)->getName() + " also matches " +
+ (*RI)->getValue("Instrs")->getValue()->getAsString());
+ }
+ assert(*RI != InstRWDef && "SchedClass has duplicate InstRW def");
+ SC.InstRWs.push_back(*RI);
+ }
}
InstrClassMap[*II] = SCIdx;
}
@@ -776,8 +880,8 @@ void CodeGenSchedModels::inferFromItinClass(Record *ItinClassDef,
void CodeGenSchedModels::inferFromInstRWs(unsigned SCIdx) {
const RecVec &RWDefs = SchedClasses[SCIdx].InstRWs;
for (RecIter RWI = RWDefs.begin(), RWE = RWDefs.end(); RWI != RWE; ++RWI) {
- RecVec Instrs = (*RWI)->getValueAsListOfDefs("Instrs");
- RecIter II = Instrs.begin(), IE = Instrs.end();
+ const RecVec *InstDefs = Sets.expand(*RWI);
+ RecIter II = InstDefs->begin(), IE = InstDefs->end();
for (; II != IE; ++II) {
if (InstrClassMap[*II] == SCIdx)
break;
@@ -797,13 +901,13 @@ void CodeGenSchedModels::inferFromInstRWs(unsigned SCIdx) {
namespace {
// Helper for substituteVariantOperand.
struct TransVariant {
- Record *VariantDef;
- unsigned RWIdx; // Index of this variant's matched type.
+ Record *VarOrSeqDef; // Variant or sequence.
+ unsigned RWIdx; // Index of this variant or sequence's matched type.
unsigned ProcIdx; // Processor model index or zero for any.
unsigned TransVecIdx; // Index into PredTransitions::TransVec.
TransVariant(Record *def, unsigned rwi, unsigned pi, unsigned ti):
- VariantDef(def), RWIdx(rwi), ProcIdx(pi), TransVecIdx(ti) {}
+ VarOrSeqDef(def), RWIdx(rwi), ProcIdx(pi), TransVecIdx(ti) {}
};
// Associate a predicate with the SchedReadWrite that it guards.
@@ -846,6 +950,9 @@ public:
private:
bool mutuallyExclusive(Record *PredDef, ArrayRef<PredCheck> Term);
+ void getIntersectingVariants(
+ const CodeGenSchedRW &SchedRW, unsigned TransIdx,
+ std::vector<TransVariant> &IntersectingVariants);
void pushVariant(const TransVariant &VInfo, bool IsRead);
};
} // anonymous
@@ -878,6 +985,137 @@ bool PredTransitions::mutuallyExclusive(Record *PredDef,
return false;
}
+static bool hasAliasedVariants(const CodeGenSchedRW &RW,
+ CodeGenSchedModels &SchedModels) {
+ if (RW.HasVariants)
+ return true;
+
+ for (RecIter I = RW.Aliases.begin(), E = RW.Aliases.end(); I != E; ++I) {
+ const CodeGenSchedRW &AliasRW =
+ SchedModels.getSchedRW((*I)->getValueAsDef("AliasRW"));
+ if (AliasRW.HasVariants)
+ return true;
+ if (AliasRW.IsSequence) {
+ IdxVec ExpandedRWs;
+ SchedModels.expandRWSequence(AliasRW.Index, ExpandedRWs, AliasRW.IsRead);
+ for (IdxIter SI = ExpandedRWs.begin(), SE = ExpandedRWs.end();
+ SI != SE; ++SI) {
+ if (hasAliasedVariants(SchedModels.getSchedRW(*SI, AliasRW.IsRead),
+ SchedModels)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+static bool hasVariant(ArrayRef<PredTransition> Transitions,
+ CodeGenSchedModels &SchedModels) {
+ for (ArrayRef<PredTransition>::iterator
+ PTI = Transitions.begin(), PTE = Transitions.end();
+ PTI != PTE; ++PTI) {
+ for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
+ WSI = PTI->WriteSequences.begin(), WSE = PTI->WriteSequences.end();
+ WSI != WSE; ++WSI) {
+ for (SmallVectorImpl<unsigned>::const_iterator
+ WI = WSI->begin(), WE = WSI->end(); WI != WE; ++WI) {
+ if (hasAliasedVariants(SchedModels.getSchedWrite(*WI), SchedModels))
+ return true;
+ }
+ }
+ for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
+ RSI = PTI->ReadSequences.begin(), RSE = PTI->ReadSequences.end();
+ RSI != RSE; ++RSI) {
+ for (SmallVectorImpl<unsigned>::const_iterator
+ RI = RSI->begin(), RE = RSI->end(); RI != RE; ++RI) {
+ if (hasAliasedVariants(SchedModels.getSchedRead(*RI), SchedModels))
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+// Populate IntersectingVariants with any variants or aliased sequences of the
+// given SchedRW whose processor indices and predicates are not mutually
+// exclusive with the given transition,
+void PredTransitions::getIntersectingVariants(
+ const CodeGenSchedRW &SchedRW, unsigned TransIdx,
+ std::vector<TransVariant> &IntersectingVariants) {
+
+ std::vector<TransVariant> Variants;
+ if (SchedRW.HasVariants) {
+ unsigned VarProcIdx = 0;
+ if (SchedRW.TheDef->getValueInit("SchedModel")->isComplete()) {
+ Record *ModelDef = SchedRW.TheDef->getValueAsDef("SchedModel");
+ VarProcIdx = SchedModels.getProcModel(ModelDef).Index;
+ }
+ // Push each variant. Assign TransVecIdx later.
+ const RecVec VarDefs = SchedRW.TheDef->getValueAsListOfDefs("Variants");
+ for (RecIter RI = VarDefs.begin(), RE = VarDefs.end(); RI != RE; ++RI)
+ Variants.push_back(TransVariant(*RI, SchedRW.Index, VarProcIdx, 0));
+ }
+ for (RecIter AI = SchedRW.Aliases.begin(), AE = SchedRW.Aliases.end();
+ AI != AE; ++AI) {
+ // If either the SchedAlias itself or the SchedReadWrite that it aliases
+ // to is defined within a processor model, constrain all variants to
+ // that processor.
+ unsigned AliasProcIdx = 0;
+ if ((*AI)->getValueInit("SchedModel")->isComplete()) {
+ Record *ModelDef = (*AI)->getValueAsDef("SchedModel");
+ AliasProcIdx = SchedModels.getProcModel(ModelDef).Index;
+ }
+ const CodeGenSchedRW &AliasRW =
+ SchedModels.getSchedRW((*AI)->getValueAsDef("AliasRW"));
+
+ if (AliasRW.HasVariants) {
+ const RecVec VarDefs = AliasRW.TheDef->getValueAsListOfDefs("Variants");
+ for (RecIter RI = VarDefs.begin(), RE = VarDefs.end(); RI != RE; ++RI)
+ Variants.push_back(TransVariant(*RI, AliasRW.Index, AliasProcIdx, 0));
+ }
+ if (AliasRW.IsSequence) {
+ Variants.push_back(
+ TransVariant(AliasRW.TheDef, SchedRW.Index, AliasProcIdx, 0));
+ }
+ }
+ for (unsigned VIdx = 0, VEnd = Variants.size(); VIdx != VEnd; ++VIdx) {
+ TransVariant &Variant = Variants[VIdx];
+ // Don't expand variants if the processor models don't intersect.
+ // A zero processor index means any processor.
+ SmallVector<unsigned, 4> &ProcIndices = TransVec[TransIdx].ProcIndices;
+ if (ProcIndices[0] && Variants[VIdx].ProcIdx) {
+ unsigned Cnt = std::count(ProcIndices.begin(), ProcIndices.end(),
+ Variant.ProcIdx);
+ if (!Cnt)
+ continue;
+ if (Cnt > 1) {
+ const CodeGenProcModel &PM =
+ *(SchedModels.procModelBegin() + Variant.ProcIdx);
+ throw TGError(Variant.VarOrSeqDef->getLoc(),
+ "Multiple variants defined for processor " + PM.ModelName +
+ " Ensure only one SchedAlias exists per RW.");
+ }
+ }
+ if (Variant.VarOrSeqDef->isSubClassOf("SchedVar")) {
+ Record *PredDef = Variant.VarOrSeqDef->getValueAsDef("Predicate");
+ if (mutuallyExclusive(PredDef, TransVec[TransIdx].PredTerm))
+ continue;
+ }
+ if (IntersectingVariants.empty()) {
+ // The first variant builds on the existing transition.
+ Variant.TransVecIdx = TransIdx;
+ IntersectingVariants.push_back(Variant);
+ }
+ else {
+ // Push another copy of the current transition for more variants.
+ Variant.TransVecIdx = TransVec.size();
+ IntersectingVariants.push_back(Variant);
+ TransVec.push_back(TransVec[TransIdx]);
+ }
+ }
+}
+
// Push the Reads/Writes selected by this variant onto the PredTransition
// specified by VInfo.
void PredTransitions::
@@ -885,17 +1123,23 @@ pushVariant(const TransVariant &VInfo, bool IsRead) {
PredTransition &Trans = TransVec[VInfo.TransVecIdx];
- Record *PredDef = VInfo.VariantDef->getValueAsDef("Predicate");
- Trans.PredTerm.push_back(PredCheck(IsRead, VInfo.RWIdx,PredDef));
-
// If this operand transition is reached through a processor-specific alias,
// then the whole transition is specific to this processor.
if (VInfo.ProcIdx != 0)
Trans.ProcIndices.assign(1, VInfo.ProcIdx);
- RecVec SelectedDefs = VInfo.VariantDef->getValueAsListOfDefs("Selected");
IdxVec SelectedRWs;
- SchedModels.findRWs(SelectedDefs, SelectedRWs, IsRead);
+ if (VInfo.VarOrSeqDef->isSubClassOf("SchedVar")) {
+ Record *PredDef = VInfo.VarOrSeqDef->getValueAsDef("Predicate");
+ Trans.PredTerm.push_back(PredCheck(IsRead, VInfo.RWIdx,PredDef));
+ RecVec SelectedDefs = VInfo.VarOrSeqDef->getValueAsListOfDefs("Selected");
+ SchedModels.findRWs(SelectedDefs, SelectedRWs, IsRead);
+ }
+ else {
+ assert(VInfo.VarOrSeqDef->isSubClassOf("WriteSequence") &&
+ "variant must be a SchedVariant or aliased WriteSequence");
+ SelectedRWs.push_back(SchedModels.getSchedRWIdx(VInfo.VarOrSeqDef, IsRead));
+ }
const CodeGenSchedRW &SchedRW = SchedModels.getSchedRW(VInfo.RWIdx, IsRead);
@@ -939,45 +1183,6 @@ pushVariant(const TransVariant &VInfo, bool IsRead) {
}
}
-static bool hasAliasedVariants(const CodeGenSchedRW &RW,
- CodeGenSchedModels &SchedModels) {
- if (RW.HasVariants)
- return true;
-
- for (RecIter I = RW.Aliases.begin(), E = RW.Aliases.end(); I != E; ++I) {
- if (SchedModels.getSchedRW((*I)->getValueAsDef("AliasRW")).HasVariants)
- return true;
- }
- return false;
-}
-
-static bool hasVariant(ArrayRef<PredTransition> Transitions,
- CodeGenSchedModels &SchedModels) {
- for (ArrayRef<PredTransition>::iterator
- PTI = Transitions.begin(), PTE = Transitions.end();
- PTI != PTE; ++PTI) {
- for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
- WSI = PTI->WriteSequences.begin(), WSE = PTI->WriteSequences.end();
- WSI != WSE; ++WSI) {
- for (SmallVectorImpl<unsigned>::const_iterator
- WI = WSI->begin(), WE = WSI->end(); WI != WE; ++WI) {
- if (hasAliasedVariants(SchedModels.getSchedWrite(*WI), SchedModels))
- return true;
- }
- }
- for (SmallVectorImpl<SmallVector<unsigned,4> >::const_iterator
- RSI = PTI->ReadSequences.begin(), RSE = PTI->ReadSequences.end();
- RSI != RSE; ++RSI) {
- for (SmallVectorImpl<unsigned>::const_iterator
- RI = RSI->begin(), RE = RSI->end(); RI != RE; ++RI) {
- if (hasAliasedVariants(SchedModels.getSchedRead(*RI), SchedModels))
- return true;
- }
- }
- }
- return false;
-}
-
// RWSeq is a sequence of all Reads or all Writes for the next read or write
// operand. StartIdx is an index into TransVec where partial results
// starts. RWSeq must be applied to all transitions between StartIdx and the end
@@ -1003,64 +1208,9 @@ void PredTransitions::substituteVariantOperand(
continue;
}
// Distribute this partial PredTransition across intersecting variants.
- RecVec Variants;
- if (SchedRW.HasVariants)
- Variants = SchedRW.TheDef->getValueAsListOfDefs("Variants");
- IdxVec VarRWIds(Variants.size(), *RWI);
- IdxVec VarProcModels(Variants.size(), 0);
- for (RecIter AI = SchedRW.Aliases.begin(), AE = SchedRW.Aliases.end();
- AI != AE; ++AI) {
- unsigned AIdx;
- const CodeGenSchedRW &AliasRW =
- SchedModels.getSchedRW((*AI)->getValueAsDef("AliasRW"), AIdx);
- if (!AliasRW.HasVariants)
- continue;
-
- RecVec AliasVars = AliasRW.TheDef->getValueAsListOfDefs("Variants");
- Variants.insert(Variants.end(), AliasVars.begin(), AliasVars.end());
-
- VarRWIds.resize(Variants.size(), AIdx);
-
- Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel");
- VarProcModels.resize(Variants.size(),
- SchedModels.getProcModel(ModelDef).Index);
- }
+ // This will push a copies of TransVec[TransIdx] on the back of TransVec.
std::vector<TransVariant> IntersectingVariants;
- for (unsigned VIdx = 0, VEnd = Variants.size(); VIdx != VEnd; ++VIdx) {
- Record *PredDef = Variants[VIdx]->getValueAsDef("Predicate");
-
- // Don't expand variants if the processor models don't intersect.
- // A zero processor index means any processor.
- SmallVector<unsigned, 4> &ProcIndices = TransVec[TransIdx].ProcIndices;
- if (ProcIndices[0] != 0 && VarProcModels[VIdx] != 0) {
- unsigned Cnt = std::count(ProcIndices.begin(), ProcIndices.end(),
- VarProcModels[VIdx]);
- if (!Cnt)
- continue;
- if (Cnt > 1) {
- const CodeGenProcModel &PM =
- *(SchedModels.procModelBegin() + VarProcModels[VIdx]);
- throw TGError(Variants[VIdx]->getLoc(), "Multiple variants defined "
- "for processor " + PM.ModelName +
- " Ensure only one SchedAlias exists per RW.");
- }
- }
- if (mutuallyExclusive(PredDef, TransVec[TransIdx].PredTerm))
- continue;
- if (IntersectingVariants.empty()) {
- // The first variant builds on the existing transition.
- IntersectingVariants.push_back(
- TransVariant(Variants[VIdx], VarRWIds[VIdx], VarProcModels[VIdx],
- TransIdx));
- }
- else {
- // Push another copy of the current transition for more variants.
- IntersectingVariants.push_back(
- TransVariant(Variants[VIdx], VarRWIds[VIdx], VarProcModels[VIdx],
- TransVec.size()));
- TransVec.push_back(TransVec[TransIdx]);
- }
- }
+ getIntersectingVariants(SchedRW, TransIdx, IntersectingVariants);
if (IntersectingVariants.empty())
throw TGError(SchedRW.TheDef->getLoc(), "No variant of this type has a "
"matching predicate on any processor ");
diff --git a/utils/TableGen/CodeGenSchedule.h b/utils/TableGen/CodeGenSchedule.h
index 226c3aed5c..cc3a10223b 100644
--- a/utils/TableGen/CodeGenSchedule.h
+++ b/utils/TableGen/CodeGenSchedule.h
@@ -15,6 +15,7 @@
#ifndef CODEGEN_SCHEDULE_H
#define CODEGEN_SCHEDULE_H
+#include "SetTheory.h"
#include "llvm/TableGen/Record.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/ADT/DenseMap.h"
@@ -43,8 +44,10 @@ void splitSchedReadWrites(const RecVec &RWDefs,
/// IsVariadic controls whether the variants are expanded into multiple operands
/// or a sequence of writes on one operand.
struct CodeGenSchedRW {
+ unsigned Index;
std::string Name;
Record *TheDef;
+ bool IsRead;
bool IsAlias;
bool HasVariants;
bool IsVariadic;
@@ -52,10 +55,12 @@ struct CodeGenSchedRW {
IdxVec Sequence;
RecVec Aliases;
- CodeGenSchedRW(): TheDef(0), IsAlias(false), HasVariants(false),
+ CodeGenSchedRW(): Index(0), TheDef(0), IsAlias(false), HasVariants(false),
IsVariadic(false), IsSequence(false) {}
- CodeGenSchedRW(Record *Def): TheDef(Def), IsAlias(false), IsVariadic(false) {
+ CodeGenSchedRW(unsigned Idx, Record *Def): Index(Idx), TheDef(Def),
+ IsAlias(false), IsVariadic(false) {
Name = Def->getName();
+ IsRead = Def->isSubClassOf("SchedRead");
HasVariants = Def->isSubClassOf("SchedVariant");
if (HasVariants)
IsVariadic = Def->getValueAsBit("Variadic");
@@ -66,9 +71,10 @@ struct CodeGenSchedRW {
IsSequence = Def->isSubClassOf("WriteSequence");
}
- CodeGenSchedRW(const IdxVec &Seq, const std::string &Name):
- Name(Name), TheDef(0), IsAlias(false), HasVariants(false),
- IsVariadic(false), IsSequence(true), Sequence(Seq) {
+ CodeGenSchedRW(unsigned Idx, bool Read, const IdxVec &Seq,
+ const std::string &Name):
+ Index(Idx), Name(Name), TheDef(0), IsRead(Read), IsAlias(false),
+ HasVariants(false), IsVariadic(false), IsSequence(true), Sequence(Seq) {
assert(Sequence.size() > 1 && "implied sequence needs >1 RWs");
}
@@ -203,6 +209,9 @@ class CodeGenSchedModels {
RecordKeeper &Records;
const CodeGenTarget &Target;
+ // Map dag expressions to Instruction lists.
+ SetTheory Sets;
+
// List of unique processor models.
std::vector<CodeGenProcModel> ProcModels;
@@ -286,15 +295,14 @@ public:
const CodeGenSchedRW &getSchedRW(unsigned Idx, bool IsRead) const {
return IsRead ? getSchedRead(Idx) : getSchedWrite(Idx);
}
- CodeGenSchedRW &getSchedRW(Record *Def, unsigned &Idx) {
+ CodeGenSchedRW &getSchedRW(Record *Def) {
bool IsRead = Def->isSubClassOf("SchedRead");
- Idx = getSchedRWIdx(Def, IsRead);
+ unsigned Idx = getSchedRWIdx(Def, IsRead);
return const_cast<CodeGenSchedRW&>(
IsRead ? getSchedRead(Idx) : getSchedWrite(Idx));
}
- CodeGenSchedRW &getSchedRW(Record *Def) {
- unsigned Idx;
- return getSchedRW(Def, Idx);
+ const CodeGenSchedRW &getSchedRW(Record*Def) const {
+ return const_cast<CodeGenSchedModels&>(*this).getSchedRW(Def);
}
unsigned getSchedRWIdx(Record *Def, bool IsRead, unsigned After = 0) const;
@@ -340,6 +348,8 @@ public:
void findRWs(const RecVec &RWDefs, IdxVec &Writes, IdxVec &Reads) const;
void findRWs(const RecVec &RWDefs, IdxVec &RWs, bool IsRead) const;
void expandRWSequence(unsigned RWIdx, IdxVec &RWSeq, bool IsRead) const;
+ void expandRWSeqForProc(unsigned RWIdx, IdxVec &RWSeq, bool IsRead,
+ const CodeGenProcModel &ProcModel) const;
unsigned addSchedClass(const IdxVec &OperWrites, const IdxVec &OperReads,
const IdxVec &ProcIndices);
diff --git a/utils/TableGen/FixedLenDecoderEmitter.cpp b/utils/TableGen/FixedLenDecoderEmitter.cpp
index e755c1ce9c..b5f62d8dea 100644
--- a/utils/TableGen/FixedLenDecoderEmitter.cpp
+++ b/utils/TableGen/FixedLenDecoderEmitter.cpp
@@ -1758,7 +1758,7 @@ static bool populateInstruction(const CodeGenInstruction &CGI, unsigned Opc,
// FIXME: This need to be extended to handle instructions with custom
// decoder methods, and operands with (simple) MIOperandInfo's.
TypedInit *TI = dynamic_cast<TypedInit*>(NI->first);
- RecordRecTy *Type = dynamic_cast<RecordRecTy*>(TI->getType());
+ RecordRecTy *Type = dyn_cast<RecordRecTy>(TI->getType());
Record *TypeRecord = Type->getRecord();
bool isReg = false;
if (TypeRecord->isSubClassOf("RegisterOperand"))
diff --git a/utils/TableGen/SetTheory.cpp b/utils/TableGen/SetTheory.cpp
index 46e6db173e..bdca9a63bd 100644
--- a/utils/TableGen/SetTheory.cpp
+++ b/utils/TableGen/SetTheory.cpp
@@ -294,7 +294,10 @@ const RecVec *SetTheory::expand(Record *Set) {
// This is the first time we see Set. Find a suitable expander.
try {
const std::vector<Record*> &SC = Set->getSuperClasses();
- for (unsigned i = 0, e = SC.size(); i != e; ++i)
+ for (unsigned i = 0, e = SC.size(); i != e; ++i) {
+ // Skip unnamed superclasses.
+ if (!dynamic_cast<const StringInit *>(SC[i]->getNameInit()))
+ continue;
if (Expander *Exp = Expanders.lookup(SC[i]->getName())) {
// This breaks recursive definitions.
RecVec &EltVec = Expansions[Set];
@@ -303,6 +306,7 @@ const RecVec *SetTheory::expand(Record *Set) {
EltVec.assign(Elts.begin(), Elts.end());
return &EltVec;
}
+ }
} catch (const std::string &Error) {
throw TGError(Set->getLoc(), Error);
}
diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp
index 4127b379b1..6ffdeb45e1 100644
--- a/utils/TableGen/SubtargetEmitter.cpp
+++ b/utils/TableGen/SubtargetEmitter.cpp
@@ -11,6 +11,8 @@
//
//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "subtarget-emitter"
+
#include "CodeGenTarget.h"
#include "CodeGenSchedule.h"
#include "llvm/ADT/StringExtras.h"
@@ -662,15 +664,16 @@ Record *SubtargetEmitter::FindWriteResources(
if (SchedWrite.TheDef->isSubClassOf("SchedWriteRes"))
return SchedWrite.TheDef;
- // Check this processor's list of aliases for SchedWrite.
Record *AliasDef = 0;
for (RecIter AI = SchedWrite.Aliases.begin(), AE = SchedWrite.Aliases.end();
AI != AE; ++AI) {
const CodeGenSchedRW &AliasRW =
SchedModels.getSchedRW((*AI)->getValueAsDef("AliasRW"));
- Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel");
- if (&SchedModels.getProcModel(ModelDef) != &ProcModel)
- continue;
+ if (AliasRW.TheDef->getValueInit("SchedModel")->isComplete()) {
+ Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel");
+ if (&SchedModels.getProcModel(ModelDef) != &ProcModel)
+ continue;
+ }
if (AliasDef)
throw TGError(AliasRW.TheDef->getLoc(), "Multiple aliases "
"defined for processor " + ProcModel.ModelName +
@@ -720,9 +723,11 @@ Record *SubtargetEmitter::FindReadAdvance(const CodeGenSchedRW &SchedRead,
AI != AE; ++AI) {
const CodeGenSchedRW &AliasRW =
SchedModels.getSchedRW((*AI)->getValueAsDef("AliasRW"));
- Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel");
- if (&SchedModels.getProcModel(ModelDef) != &ProcModel)
- continue;
+ if (AliasRW.TheDef->getValueInit("SchedModel")->isComplete()) {
+ Record *ModelDef = AliasRW.TheDef->getValueAsDef("SchedModel");
+ if (&SchedModels.getProcModel(ModelDef) != &ProcModel)
+ continue;
+ }
if (AliasDef)
throw TGError(AliasRW.TheDef->getLoc(), "Multiple aliases "
"defined for processor " + ProcModel.ModelName +
@@ -769,6 +774,8 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
std::vector<MCSchedClassDesc> &SCTab = SchedTables.ProcSchedClasses.back();
for (CodeGenSchedModels::SchedClassIter SCI = SchedModels.schedClassBegin(),
SCE = SchedModels.schedClassEnd(); SCI != SCE; ++SCI) {
+ DEBUG(SCI->dump(&SchedModels));
+
SCTab.resize(SCTab.size() + 1);
MCSchedClassDesc &SCDesc = SCTab.back();
// SCDesc.Name is guarded by NDEBUG
@@ -817,8 +824,8 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
}
}
else if (!SCI->InstRWs.empty()) {
- assert(SCI->Writes.empty() && SCI->Reads.empty() &&
- "InstRW class should not have its own ReadWrites");
+ // This class may have a default ReadWrite list which can be overriden by
+ // InstRW definitions.
Record *RWDef = 0;
for (RecIter RWI = SCI->InstRWs.begin(), RWE = SCI->InstRWs.end();
RWI != RWE; ++RWI) {
@@ -829,6 +836,8 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
}
}
if (RWDef) {
+ Writes.clear();
+ Reads.clear();
SchedModels.findRWs(RWDef->getValueAsListOfDefs("OperandReadWrites"),
Writes, Reads);
}
@@ -840,7 +849,8 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
std::vector<MCReadAdvanceEntry> ReadAdvanceEntries;
for (IdxIter WI = Writes.begin(), WE = Writes.end(); WI != WE; ++WI) {
IdxVec WriteSeq;
- SchedModels.expandRWSequence(*WI, WriteSeq, /*IsRead=*/false);
+ SchedModels.expandRWSeqForProc(*WI, WriteSeq, /*IsRead=*/false,
+ ProcModel);
// For each operand, create a latency entry.
MCWriteLatencyEntry WLEntry;
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
index 9695b4a351..49efe7ed73 100644
--- a/utils/TableGen/TableGen.cpp
+++ b/utils/TableGen/TableGen.cpp
@@ -20,7 +20,6 @@
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Main.h"
#include "llvm/TableGen/Record.h"
-#include "llvm/TableGen/TableGenAction.h"
using namespace llvm;
@@ -90,86 +89,83 @@ namespace {
Class("class", cl::desc("Print Enum list for this class"),
cl::value_desc("class name"));
- class LLVMTableGenAction : public TableGenAction {
- public:
- bool operator()(raw_ostream &OS, RecordKeeper &Records) {
- switch (Action) {
- case PrintRecords:
- OS << Records; // No argument, dump all contents
- break;
- case GenEmitter:
- EmitCodeEmitter(Records, OS);
- break;
- case GenRegisterInfo:
- EmitRegisterInfo(Records, OS);
- break;
- case GenInstrInfo:
- EmitInstrInfo(Records, OS);
- break;
- case GenCallingConv:
- EmitCallingConv(Records, OS);
- break;
- case GenAsmWriter:
- EmitAsmWriter(Records, OS);
- break;
- case GenAsmMatcher:
- EmitAsmMatcher(Records, OS);
- break;
- case GenDisassembler:
- EmitDisassembler(Records, OS);
- break;
- case GenPseudoLowering:
- EmitPseudoLowering(Records, OS);
- break;
- case GenDAGISel:
- EmitDAGISel(Records, OS);
- break;
- case GenDFAPacketizer:
- EmitDFAPacketizer(Records, OS);
- break;
- case GenFastISel:
- EmitFastISel(Records, OS);
- break;
- case GenSubtarget:
- EmitSubtarget(Records, OS);
- break;
- case GenIntrinsic:
- EmitIntrinsics(Records, OS);
- break;
- case GenTgtIntrinsic:
- EmitIntrinsics(Records, OS, true);
- break;
- case GenEDInfo:
- EmitEnhancedDisassemblerInfo(Records, OS);
- break;
- case PrintEnums:
- {
- std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);
- for (unsigned i = 0, e = Recs.size(); i != e; ++i)
- OS << Recs[i]->getName() << ", ";
- OS << "\n";
- break;
- }
- case PrintSets:
- {
- SetTheory Sets;
- Sets.addFieldExpander("Set", "Elements");
- std::vector<Record*> Recs = Records.getAllDerivedDefinitions("Set");
- for (unsigned i = 0, e = Recs.size(); i != e; ++i) {
- OS << Recs[i]->getName() << " = [";
- const std::vector<Record*> *Elts = Sets.expand(Recs[i]);
- assert(Elts && "Couldn't expand Set instance");
- for (unsigned ei = 0, ee = Elts->size(); ei != ee; ++ei)
- OS << ' ' << (*Elts)[ei]->getName();
- OS << " ]\n";
- }
- break;
- }
- }
-
- return false;
+bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
+ switch (Action) {
+ case PrintRecords:
+ OS << Records; // No argument, dump all contents
+ break;
+ case GenEmitter:
+ EmitCodeEmitter(Records, OS);
+ break;
+ case GenRegisterInfo:
+ EmitRegisterInfo(Records, OS);
+ break;
+ case GenInstrInfo:
+ EmitInstrInfo(Records, OS);
+ break;
+ case GenCallingConv:
+ EmitCallingConv(Records, OS);
+ break;
+ case GenAsmWriter:
+ EmitAsmWriter(Records, OS);
+ break;
+ case GenAsmMatcher:
+ EmitAsmMatcher(Records, OS);
+ break;
+ case GenDisassembler:
+ EmitDisassembler(Records, OS);
+ break;
+ case GenPseudoLowering:
+ EmitPseudoLowering(Records, OS);
+ break;
+ case GenDAGISel:
+ EmitDAGISel(Records, OS);
+ break;
+ case GenDFAPacketizer:
+ EmitDFAPacketizer(Records, OS);
+ break;
+ case GenFastISel:
+ EmitFastISel(Records, OS);
+ break;
+ case GenSubtarget:
+ EmitSubtarget(Records, OS);
+ break;
+ case GenIntrinsic:
+ EmitIntrinsics(Records, OS);
+ break;
+ case GenTgtIntrinsic:
+ EmitIntrinsics(Records, OS, true);
+ break;
+ case GenEDInfo:
+ EmitEnhancedDisassemblerInfo(Records, OS);
+ break;
+ case PrintEnums:
+ {
+ std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);
+ for (unsigned i = 0, e = Recs.size(); i != e; ++i)
+ OS << Recs[i]->getName() << ", ";
+ OS << "\n";
+ break;
+ }
+ case PrintSets:
+ {
+ SetTheory Sets;
+ Sets.addFieldExpander("Set", "Elements");
+ std::vector<Record*> Recs = Records.getAllDerivedDefinitions("Set");
+ for (unsigned i = 0, e = Recs.size(); i != e; ++i) {
+ OS << Recs[i]->getName() << " = [";
+ const std::vector<Record*> *Elts = Sets.expand(Recs[i]);
+ assert(Elts && "Couldn't expand Set instance");
+ for (unsigned ei = 0, ee = Elts->size(); ei != ee; ++ei)
+ OS << ' ' << (*Elts)[ei]->getName();
+ OS << " ]\n";
}
- };
+ break;
+ }
+ }
+
+ return false;
+}
}
int main(int argc, char **argv) {
@@ -177,6 +173,5 @@ int main(int argc, char **argv) {
PrettyStackTraceProgram X(argc, argv);
cl::ParseCommandLineOptions(argc, argv);
- LLVMTableGenAction Action;
- return TableGenMain(argv[0], Action);
+ return TableGenMain(argv[0], &LLVMTableGenMain);
}