summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-01-23 11:09:33 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-01-23 11:09:33 +0000
commit3fd58f91dd318518f7daa4ba64c0aaf31799d89b (patch)
tree74eecbae571601ec6a626a53374b1eddc7b164a5
parent3fba7d16b41dfbefe3b1be6bc0ab94c017728f79 (diff)
downloadFreeBSD-src-3fd58f91dd318518f7daa4ba64c0aaf31799d89b.zip
FreeBSD-src-3fd58f91dd318518f7daa4ba64c0aaf31799d89b.tar.gz
Update LLVM to r94309.
-rw-r--r--CMakeLists.txt1
-rw-r--r--Makefile3
-rw-r--r--Makefile.rules26
-rw-r--r--bindings/ocaml/llvm/llvm.ml3
-rw-r--r--bindings/ocaml/llvm/llvm.mli1
-rw-r--r--bindings/ocaml/llvm/llvm_ocaml.c6
-rw-r--r--cmake/modules/LLVMLibDeps.cmake11
-rw-r--r--docs/BitCodeFormat.html5
-rw-r--r--docs/LangRef.html83
-rw-r--r--docs/ReleaseNotes.html3
-rw-r--r--include/llvm-c/Core.h5
-rw-r--r--include/llvm/ADT/DenseMapInfo.h13
-rw-r--r--include/llvm/ADT/ImmutableMap.h2
-rw-r--r--include/llvm/ADT/ImmutableSet.h113
-rw-r--r--include/llvm/Analysis/DOTGraphTraitsPass.h83
-rw-r--r--include/llvm/Analysis/DebugInfo.h17
-rw-r--r--include/llvm/Analysis/DominatorInternals.h14
-rw-r--r--include/llvm/Analysis/IVUsers.h5
-rw-r--r--include/llvm/Analysis/LoopPass.h7
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h6
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpander.h69
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpressions.h7
-rw-r--r--include/llvm/Attributes.h4
-rw-r--r--include/llvm/CallGraphSCCPass.h4
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h110
-rw-r--r--include/llvm/CodeGen/FileWriters.h10
-rw-r--r--include/llvm/CodeGen/LinkAllCodegenComponents.h1
-rw-r--r--include/llvm/CodeGen/MachineBasicBlock.h4
-rw-r--r--include/llvm/CodeGen/MachineFunction.h8
-rw-r--r--include/llvm/CodeGen/MachineModuleInfo.h3
-rw-r--r--include/llvm/CodeGen/MachineOperand.h4
-rw-r--r--include/llvm/CodeGen/Passes.h4
-rw-r--r--include/llvm/CodeGen/SchedulerRegistry.h5
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h11
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h53
-rw-r--r--include/llvm/InstrTypes.h4
-rw-r--r--include/llvm/IntrinsicInst.h8
-rw-r--r--include/llvm/LinkAllVMCore.h4
-rw-r--r--include/llvm/MC/MCAsmInfo.h124
-rw-r--r--include/llvm/MC/MCDirectives.h44
-rw-r--r--include/llvm/MC/MCExpr.h7
-rw-r--r--include/llvm/MC/MCParser/AsmCond.h40
-rw-r--r--include/llvm/MC/MCParser/AsmLexer.h72
-rw-r--r--include/llvm/MC/MCParser/AsmParser.h178
-rw-r--r--include/llvm/MC/MCParser/MCAsmLexer.h (renamed from include/llvm/MC/MCAsmLexer.h)33
-rw-r--r--include/llvm/MC/MCParser/MCAsmParser.h (renamed from include/llvm/MC/MCAsmParser.h)15
-rw-r--r--include/llvm/MC/MCParser/MCParsedAsmOperand.h (renamed from include/llvm/MC/MCParsedAsmOperand.h)0
-rw-r--r--include/llvm/MC/MCSectionELF.h5
-rw-r--r--include/llvm/MC/MCStreamer.h91
-rw-r--r--include/llvm/MC/MCSymbol.h17
-rw-r--r--include/llvm/MC/MCValue.h1
-rw-r--r--include/llvm/MC/SectionKind.h23
-rw-r--r--include/llvm/Metadata.h25
-rw-r--r--include/llvm/Pass.h46
-rw-r--r--include/llvm/PassAnalysisSupport.h42
-rw-r--r--include/llvm/PassManagers.h6
-rw-r--r--include/llvm/PassSupport.h5
-rw-r--r--include/llvm/Support/CFG.h2
-rw-r--r--include/llvm/Support/DebugLoc.h53
-rw-r--r--include/llvm/Support/Mangler.h142
-rw-r--r--include/llvm/Support/PassNameParser.h4
-rw-r--r--include/llvm/Support/SMLoc.h44
-rw-r--r--include/llvm/Support/SourceMgr.h24
-rw-r--r--include/llvm/Support/raw_ostream.h5
-rw-r--r--include/llvm/System/Host.h13
-rw-r--r--include/llvm/Target/Mangler.h75
-rw-r--r--include/llvm/Target/Target.td2
-rw-r--r--include/llvm/Target/TargetAsmLexer.h79
-rw-r--r--include/llvm/Target/TargetAsmParser.h1
-rw-r--r--include/llvm/Target/TargetInstrInfo.h24
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h2
-rw-r--r--include/llvm/Target/TargetMachine.h35
-rw-r--r--include/llvm/Target/TargetRegistry.h54
-rw-r--r--include/llvm/Transforms/IPO/InlinerPass.h6
-rw-r--r--include/llvm/Transforms/Utils/Local.h7
-rw-r--r--lib/Analysis/AliasAnalysisCounter.cpp14
-rw-r--r--lib/Analysis/AliasDebugger.cpp10
-rw-r--r--lib/Analysis/BasicAliasAnalysis.cpp20
-rw-r--r--lib/Analysis/DebugInfo.cpp60
-rw-r--r--lib/Analysis/DomPrinter.cpp74
-rw-r--r--lib/Analysis/IPA/Andersens.cpp10
-rw-r--r--lib/Analysis/IPA/CallGraph.cpp12
-rw-r--r--lib/Analysis/IPA/CallGraphSCCPass.cpp57
-rw-r--r--lib/Analysis/IPA/GlobalsModRef.cpp10
-rw-r--r--lib/Analysis/IPA/Makefile2
-rw-r--r--lib/Analysis/IVUsers.cpp19
-rw-r--r--lib/Analysis/LoopPass.cpp45
-rw-r--r--lib/Analysis/Makefile1
-rw-r--r--lib/Analysis/ProfileEstimatorPass.cpp10
-rw-r--r--lib/Analysis/ProfileInfo.cpp14
-rw-r--r--lib/Analysis/ProfileInfoLoaderPass.cpp10
-rw-r--r--lib/Analysis/ScalarEvolution.cpp212
-rw-r--r--lib/Analysis/ScalarEvolutionAliasAnalysis.cpp10
-rw-r--r--lib/Analysis/ScalarEvolutionExpander.cpp238
-rw-r--r--lib/Archive/Makefile1
-rw-r--r--lib/AsmParser/LLLexer.cpp1
-rw-r--r--lib/AsmParser/LLParser.cpp1
-rw-r--r--lib/AsmParser/LLParser.h1
-rw-r--r--lib/AsmParser/LLToken.h1
-rw-r--r--lib/AsmParser/Makefile1
-rw-r--r--lib/AsmParser/Parser.cpp3
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp2
-rw-r--r--lib/Bitcode/Reader/Makefile1
-rw-r--r--lib/Bitcode/Writer/Makefile1
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.cpp9
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.h2
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp1452
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.cpp70
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.h29
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp387
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h18
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.cpp191
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.h10
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfPrinter.cpp214
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfPrinter.h266
-rw-r--r--lib/CodeGen/AsmPrinter/Makefile5
-rw-r--r--lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp13
-rw-r--r--lib/CodeGen/CMakeLists.txt2
-rw-r--r--lib/CodeGen/DwarfEHPrepare.cpp13
-rw-r--r--lib/CodeGen/ELFWriter.cpp18
-rw-r--r--lib/CodeGen/LLVMTargetMachine.cpp25
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp12
-rw-r--r--lib/CodeGen/MachO.h412
-rw-r--r--lib/CodeGen/MachOCodeEmitter.cpp193
-rw-r--r--lib/CodeGen/MachOCodeEmitter.h69
-rw-r--r--lib/CodeGen/MachOWriter.cpp785
-rw-r--r--lib/CodeGen/MachOWriter.h192
-rw-r--r--lib/CodeGen/MachineBasicBlock.cpp21
-rw-r--r--lib/CodeGen/MachineFunction.cpp7
-rw-r--r--lib/CodeGen/MachineInstr.cpp17
-rw-r--r--lib/CodeGen/Makefile1
-rw-r--r--lib/CodeGen/MaxStackAlignment.cpp70
-rw-r--r--lib/CodeGen/OptimizeExts.cpp12
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp23
-rw-r--r--lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp1
-rw-r--r--lib/CodeGen/SelectionDAG/InstrEmitter.cpp1
-rw-r--r--lib/CodeGen/SelectionDAG/Makefile3
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp1
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp70
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp124
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h4
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp98
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp1095
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp4
-rw-r--r--lib/CodeGen/SlotIndexes.cpp3
-rw-r--r--lib/CodeGen/TailDuplication.cpp34
-rw-r--r--lib/ExecutionEngine/Interpreter/Makefile2
-rw-r--r--lib/ExecutionEngine/JIT/JITEmitter.cpp10
-rw-r--r--lib/ExecutionEngine/JIT/Makefile2
-rw-r--r--lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp20
-rw-r--r--lib/ExecutionEngine/Makefile1
-rw-r--r--lib/Linker/LinkModules.cpp2
-rw-r--r--lib/Linker/Makefile1
-rw-r--r--lib/MC/CMakeLists.txt3
-rw-r--r--lib/MC/MCAsmInfo.cpp17
-rw-r--r--lib/MC/MCAsmInfoCOFF.cpp7
-rw-r--r--lib/MC/MCAsmInfoDarwin.cpp17
-rw-r--r--lib/MC/MCAsmStreamer.cpp352
-rw-r--r--lib/MC/MCAssembler.cpp2
-rw-r--r--lib/MC/MCExpr.cpp29
-rw-r--r--lib/MC/MCInst.cpp4
-rw-r--r--lib/MC/MCMachOStreamer.cpp71
-rw-r--r--lib/MC/MCNullStreamer.cpp12
-rw-r--r--lib/MC/MCParser/AsmLexer.cpp320
-rw-r--r--lib/MC/MCParser/AsmParser.cpp1781
-rw-r--r--lib/MC/MCParser/CMakeLists.txt7
-rw-r--r--lib/MC/MCParser/MCAsmLexer.cpp (renamed from lib/MC/MCAsmLexer.cpp)2
-rw-r--r--lib/MC/MCParser/MCAsmParser.cpp35
-rw-r--r--lib/MC/MCParser/Makefile16
-rw-r--r--lib/MC/MCParser/TargetAsmParser.cpp (renamed from lib/MC/TargetAsmParser.cpp)0
-rw-r--r--lib/MC/MCSectionELF.cpp12
-rw-r--r--lib/MC/MCStreamer.cpp25
-rw-r--r--lib/MC/MCSymbol.cpp77
-rw-r--r--lib/MC/MCValue.cpp8
-rw-r--r--lib/MC/Makefile2
-rw-r--r--lib/Support/Debug.cpp4
-rw-r--r--lib/Support/SourceMgr.cpp21
-rw-r--r--lib/Support/StringExtras.cpp4
-rw-r--r--lib/Support/raw_ostream.cpp11
-rw-r--r--lib/System/Host.cpp4
-rw-r--r--lib/System/Unix/TimeValue.inc2
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.cpp4
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.cpp8
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.h1
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp4
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp23
-rw-r--r--lib/Target/ARM/ARMISelLowering.h2
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td23
-rw-r--r--lib/Target/ARM/ARMInstrNEON.td65
-rw-r--r--lib/Target/ARM/ARMInstrThumb.td20
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td16
-rw-r--r--lib/Target/ARM/ARMMCAsmInfo.cpp2
-rw-r--r--lib/Target/ARM/ARMTargetMachine.cpp4
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp138
-rw-r--r--lib/Target/ARM/AsmParser/Makefile1
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp239
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp2
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp14
-rw-r--r--lib/Target/ARM/AsmPrinter/Makefile1
-rw-r--r--lib/Target/ARM/Makefile1
-rw-r--r--lib/Target/ARM/README.txt9
-rw-r--r--lib/Target/ARM/TargetInfo/Makefile1
-rw-r--r--lib/Target/ARM/Thumb1InstrInfo.cpp8
-rw-r--r--lib/Target/ARM/Thumb1RegisterInfo.cpp8
-rw-r--r--lib/Target/ARM/Thumb2InstrInfo.cpp10
-rw-r--r--lib/Target/ARM/Thumb2SizeReduction.cpp3
-rw-r--r--lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp82
-rw-r--r--lib/Target/Alpha/AsmPrinter/Makefile1
-rw-r--r--lib/Target/Alpha/Makefile2
-rw-r--r--lib/Target/Alpha/TargetInfo/Makefile1
-rw-r--r--lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp58
-rw-r--r--lib/Target/Blackfin/AsmPrinter/Makefile1
-rw-r--r--lib/Target/Blackfin/Makefile2
-rw-r--r--lib/Target/Blackfin/TargetInfo/Makefile1
-rw-r--r--lib/Target/CBackend/CBackend.cpp75
-rw-r--r--lib/Target/CBackend/Makefile1
-rw-r--r--lib/Target/CBackend/TargetInfo/Makefile1
-rw-r--r--lib/Target/CMakeLists.txt2
-rw-r--r--lib/Target/CellSPU/AsmPrinter/Makefile1
-rw-r--r--lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp129
-rw-r--r--lib/Target/CellSPU/Makefile1
-rw-r--r--lib/Target/CellSPU/SPUMCAsmInfo.cpp2
-rw-r--r--lib/Target/CellSPU/TargetInfo/Makefile1
-rw-r--r--lib/Target/CppBackend/CPPBackend.cpp1
-rw-r--r--lib/Target/CppBackend/Makefile1
-rw-r--r--lib/Target/CppBackend/TargetInfo/Makefile1
-rw-r--r--lib/Target/MSIL/MSILWriter.cpp10
-rw-r--r--lib/Target/MSIL/MSILWriter.h2
-rw-r--r--lib/Target/MSIL/Makefile1
-rw-r--r--lib/Target/MSIL/TargetInfo/Makefile1
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp111
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp8
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp14
-rw-r--r--lib/Target/MSP430/AsmPrinter/Makefile1
-rw-r--r--lib/Target/MSP430/CMakeLists.txt3
-rw-r--r--lib/Target/MSP430/MSP430.h2
-rw-r--r--lib/Target/MSP430/MSP430.td10
-rw-r--r--lib/Target/MSP430/MSP430BranchSelector.cpp179
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.cpp67
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.h17
-rw-r--r--lib/Target/MSP430/MSP430InstrFormats.td166
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.cpp42
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.h18
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.td1340
-rw-r--r--lib/Target/MSP430/MSP430TargetMachine.cpp6
-rw-r--r--lib/Target/MSP430/MSP430TargetMachine.h1
-rw-r--r--lib/Target/MSP430/Makefile2
-rw-r--r--lib/Target/MSP430/TargetInfo/Makefile1
-rw-r--r--lib/Target/Makefile1
-rw-r--r--lib/Target/Mangler.cpp179
-rw-r--r--lib/Target/Mips/AsmPrinter/Makefile1
-rw-r--r--lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp121
-rw-r--r--lib/Target/Mips/Makefile2
-rw-r--r--lib/Target/Mips/MipsCallingConv.td8
-rw-r--r--lib/Target/Mips/MipsISelDAGToDAG.cpp54
-rw-r--r--lib/Target/Mips/MipsInstrInfo.cpp9
-rw-r--r--lib/Target/Mips/MipsInstrInfo.td10
-rw-r--r--lib/Target/Mips/MipsRegisterInfo.cpp2
-rw-r--r--lib/Target/Mips/TargetInfo/Makefile1
-rw-r--r--lib/Target/PIC16/AsmPrinter/Makefile1
-rw-r--r--lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp82
-rw-r--r--lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h4
-rw-r--r--lib/Target/PIC16/Makefile2
-rw-r--r--lib/Target/PIC16/PIC16DebugInfo.cpp5
-rw-r--r--lib/Target/PIC16/PIC16Passes/Makefile1
-rw-r--r--lib/Target/PIC16/TargetInfo/Makefile1
-rw-r--r--lib/Target/PowerPC/AsmPrinter/Makefile1
-rw-r--r--lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp563
-rw-r--r--lib/Target/PowerPC/Makefile2
-rw-r--r--lib/Target/PowerPC/PPCMCAsmInfo.cpp3
-rw-r--r--lib/Target/PowerPC/PPCTargetMachine.cpp29
-rw-r--r--lib/Target/PowerPC/PPCTargetMachine.h12
-rw-r--r--lib/Target/PowerPC/TargetInfo/Makefile1
-rw-r--r--lib/Target/README.txt51
-rw-r--r--lib/Target/Sparc/AsmPrinter/Makefile2
-rw-r--r--lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp97
-rw-r--r--lib/Target/Sparc/Makefile2
-rw-r--r--lib/Target/Sparc/TargetInfo/Makefile1
-rw-r--r--lib/Target/SystemZ/AsmPrinter/Makefile1
-rw-r--r--lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp116
-rw-r--r--lib/Target/SystemZ/Makefile2
-rw-r--r--lib/Target/SystemZ/SystemZMCAsmInfo.cpp6
-rw-r--r--lib/Target/SystemZ/SystemZMCAsmInfo.h3
-rw-r--r--lib/Target/SystemZ/TargetInfo/Makefile1
-rw-r--r--lib/Target/TargetAsmLexer.cpp (renamed from lib/MC/MCAsmParser.cpp)12
-rw-r--r--lib/Target/TargetLoweringObjectFile.cpp98
-rw-r--r--lib/Target/TargetMachine.cpp6
-rw-r--r--lib/Target/X86/AsmParser/CMakeLists.txt1
-rw-r--r--lib/Target/X86/AsmParser/Makefile1
-rw-r--r--lib/Target/X86/AsmParser/X86AsmLexer.cpp43
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp239
-rw-r--r--lib/Target/X86/AsmPrinter/Makefile1
-rw-r--r--lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp7
-rw-r--r--lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp314
-rw-r--r--lib/Target/X86/AsmPrinter/X86AsmPrinter.h1
-rw-r--r--lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp6
-rw-r--r--lib/Target/X86/AsmPrinter/X86MCInstLower.cpp52
-rw-r--r--lib/Target/X86/Disassembler/Makefile1
-rw-r--r--lib/Target/X86/Makefile2
-rw-r--r--lib/Target/X86/TargetInfo/Makefile2
-rw-r--r--lib/Target/X86/X86COFFMachineModuleInfo.cpp11
-rw-r--r--lib/Target/X86/X86COFFMachineModuleInfo.h4
-rw-r--r--lib/Target/X86/X86FastISel.cpp4
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp8
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp17
-rw-r--r--lib/Target/X86/X86Instr64bit.td2
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp146
-rw-r--r--lib/Target/X86/X86InstrInfo.h20
-rw-r--r--lib/Target/X86/X86MCAsmInfo.cpp9
-rw-r--r--lib/Target/X86/X86MCAsmInfo.h1
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp21
-rw-r--r--lib/Target/X86/X86RegisterInfo.h2
-rw-r--r--lib/Target/X86/X86TargetMachine.cpp32
-rw-r--r--lib/Target/X86/X86TargetMachine.h12
-rw-r--r--lib/Target/X86/X86TargetObjectFile.cpp7
-rw-r--r--lib/Target/XCore/AsmPrinter/Makefile1
-rw-r--r--lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp105
-rw-r--r--lib/Target/XCore/Makefile2
-rw-r--r--lib/Target/XCore/TargetInfo/Makefile2
-rw-r--r--lib/Transforms/Hello/Makefile1
-rw-r--r--lib/Transforms/IPO/Inliner.cpp26
-rw-r--r--lib/Transforms/IPO/Makefile1
-rw-r--r--lib/Transforms/IPO/StripSymbols.cpp2
-rw-r--r--lib/Transforms/InstCombine/InstCombineAndOrXor.cpp5
-rw-r--r--lib/Transforms/InstCombine/InstCombineCasts.cpp13
-rw-r--r--lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp9
-rw-r--r--lib/Transforms/InstCombine/InstCombineMulDivRem.cpp2
-rw-r--r--lib/Transforms/InstCombine/InstCombineShifts.cpp24
-rw-r--r--lib/Transforms/InstCombine/Makefile1
-rw-r--r--lib/Transforms/Instrumentation/Makefile1
-rw-r--r--lib/Transforms/Instrumentation/OptimalEdgeProfiling.cpp2
-rw-r--r--lib/Transforms/Scalar/CodeGenPrepare.cpp29
-rw-r--r--lib/Transforms/Scalar/GVN.cpp99
-rw-r--r--lib/Transforms/Scalar/IndVarSimplify.cpp14
-rw-r--r--lib/Transforms/Scalar/Makefile1
-rw-r--r--lib/Transforms/Scalar/ScalarReplAggregates.cpp82
-rw-r--r--lib/Transforms/Scalar/SimplifyLibCalls.cpp47
-rw-r--r--lib/Transforms/Utils/BasicBlockUtils.cpp5
-rw-r--r--lib/Transforms/Utils/Local.cpp24
-rw-r--r--lib/Transforms/Utils/LoopSimplify.cpp2
-rw-r--r--lib/Transforms/Utils/Makefile1
-rw-r--r--lib/Transforms/Utils/PromoteMemoryToRegister.cpp61
-rw-r--r--lib/Transforms/Utils/ValueMapper.cpp30
-rw-r--r--lib/VMCore/AsmWriter.cpp4
-rw-r--r--lib/VMCore/Attributes.cpp2
-rw-r--r--lib/VMCore/AutoUpgrade.cpp2
-rw-r--r--lib/VMCore/CMakeLists.txt1
-rw-r--r--lib/VMCore/ConstantFold.cpp5
-rw-r--r--lib/VMCore/Constants.cpp20
-rw-r--r--lib/VMCore/Instructions.cpp13
-rw-r--r--lib/VMCore/IntrinsicInst.cpp11
-rw-r--r--lib/VMCore/Makefile1
-rw-r--r--lib/VMCore/Mangler.cpp273
-rw-r--r--lib/VMCore/Metadata.cpp97
-rw-r--r--lib/VMCore/Pass.cpp3
-rw-r--r--lib/VMCore/PassManager.cpp76
-rw-r--r--lib/VMCore/Verifier.cpp17
-rw-r--r--projects/CMakeLists.txt4
-rw-r--r--projects/Makefile3
-rw-r--r--test/Analysis/PostDominators/pr6047_a.ll15
-rw-r--r--test/Analysis/PostDominators/pr6047_b.ll19
-rw-r--r--test/Analysis/PostDominators/pr6047_c.ll147
-rw-r--r--test/Analysis/PostDominators/pr6047_d.ll24
-rw-r--r--test/Assembler/functionlocal-metadata.ll9
-rw-r--r--test/CodeGen/ARM/ctz.ll11
-rw-r--r--test/CodeGen/ARM/indirectbr.ll4
-rw-r--r--test/CodeGen/ARM/vbits.ll12
-rw-r--r--test/CodeGen/CellSPU/call_indirect.ll4
-rw-r--r--test/CodeGen/Generic/GC/frame_size.ll14
-rw-r--r--test/CodeGen/MSP430/bit.ll1
-rw-r--r--test/CodeGen/MSP430/setcc.ll13
-rw-r--r--test/CodeGen/PIC16/globals.ll6
-rw-r--r--test/CodeGen/PowerPC/2008-12-12-EH.ll1
-rw-r--r--test/CodeGen/PowerPC/sections.ll2
-rw-r--r--test/CodeGen/PowerPC/stubs.ll22
-rw-r--r--test/CodeGen/Thumb/2009-12-17-pre-regalloc-taildup.ll2
-rw-r--r--test/CodeGen/Thumb/2010-01-15-local-alloc-spill-physical.ll20
-rw-r--r--test/CodeGen/Thumb2/2010-01-06-TailDuplicateLabels.ll2
-rw-r--r--test/CodeGen/Thumb2/2010-01-19-RemovePredicates.ll53
-rw-r--r--test/CodeGen/X86/2007-08-13-SpillerReuse.ll102
-rw-r--r--test/CodeGen/X86/2008-04-02-unnamedEH.ll20
-rw-r--r--test/CodeGen/X86/2008-09-18-inline-asm-2.ll4
-rw-r--r--test/CodeGen/X86/2008-12-19-EarlyClobberBug.ll2
-rw-r--r--test/CodeGen/X86/2009-02-04-sext-i64-gep.ll2
-rw-r--r--test/CodeGen/X86/2009-09-10-SpillComments.ll9
-rw-r--r--test/CodeGen/X86/2010-01-15-SelectionDAGCycle.ll28
-rw-r--r--test/CodeGen/X86/2010-01-19-OptExtBug.ll57
-rw-r--r--test/CodeGen/X86/bigstructret2.ll12
-rw-r--r--test/CodeGen/X86/bss_pagealigned.ll2
-rw-r--r--test/CodeGen/X86/full-lsr.ll12
-rw-r--r--test/CodeGen/X86/global-sections.ll20
-rw-r--r--test/CodeGen/X86/i128-and-beyond.ll2
-rw-r--r--test/CodeGen/X86/illegal-asm.ll34
-rw-r--r--test/CodeGen/X86/loop-hoist.ll2
-rw-r--r--test/CodeGen/X86/loop-strength-reduce4.ll2
-rw-r--r--test/CodeGen/X86/neg-shl-add.ll17
-rw-r--r--test/CodeGen/X86/pr3495-2.ll1
-rw-r--r--test/CodeGen/X86/pr3495.ll6
-rw-r--r--test/CodeGen/X86/ptrtoint-constexpr.ll2
-rw-r--r--test/CodeGen/X86/remat-mov-0.ll26
-rw-r--r--test/CodeGen/X86/remat-mov-1.ll40
-rw-r--r--test/CodeGen/X86/remat-scalar-zero.ll2
-rw-r--r--test/CodeGen/X86/splat-scalar-load.ll26
-rw-r--r--test/CodeGen/X86/stride-reuse.ll2
-rw-r--r--test/CodeGen/X86/subreg-to-reg-5.ll35
-rw-r--r--test/CodeGen/X86/tail-opts.ll6
-rw-r--r--test/CodeGen/X86/unaligned-load.ll4
-rw-r--r--test/CodeGen/X86/xor.ll11
-rw-r--r--test/DebugInfo/2010-01-19-DbgScope.ll28
-rw-r--r--test/FrontendC/2010-01-18-Inlined-Debug.c12
-rw-r--r--test/FrontendC/pr5406.c20
-rw-r--r--test/MC/AsmParser/X86/x86_instructions.s4
-rw-r--r--test/MC/AsmParser/directive_ascii.s19
-rw-r--r--test/MC/AsmParser/directive_lcomm.s2
-rw-r--r--test/MC/AsmParser/directive_space.s7
-rw-r--r--test/Transforms/ConstProp/constant-expr.ll9
-rw-r--r--test/Transforms/IndVarSimplify/gep-with-mul-base.ll5
-rw-r--r--test/Transforms/InstCombine/apint-elim-logicalops.ll39
-rw-r--r--test/Transforms/InstCombine/bitcast-sext-vector.ll11
-rw-r--r--test/Transforms/InstCombine/canonicalize_branch.ll36
-rw-r--r--test/Transforms/InstCombine/fsub-fadd.ll39
-rw-r--r--test/Transforms/InstCombine/fsub-fsub.ll8
-rw-r--r--test/Transforms/InstCombine/fsub.ll23
-rw-r--r--test/Transforms/InstCombine/idioms.ll32
-rw-r--r--test/Transforms/InstCombine/signext.ll39
-rw-r--r--test/Transforms/InstCombine/xor2.ll10
-rw-r--r--test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-0.ll2
-rw-r--r--test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll8
-rw-r--r--test/Transforms/LoopStrengthReduce/icmp_use_postinc.ll27
-rw-r--r--test/Transforms/LoopStrengthReduce/related_indvars.ll2
-rw-r--r--test/Transforms/Mem2Reg/ConvertDebugInfo.ll31
-rw-r--r--test/Transforms/Reassociate/inverses.ll32
-rw-r--r--test/Transforms/ScalarRepl/2010-01-18-SelfCopy.ll18
-rw-r--r--test/lit.cfg2
-rw-r--r--tools/bugpoint/Miscompilation.cpp37
-rw-r--r--tools/gold/Makefile1
-rw-r--r--tools/llc/Makefile1
-rw-r--r--tools/llc/llc.cpp2
-rw-r--r--tools/lli/Makefile1
-rw-r--r--tools/llvm-ar/Makefile1
-rw-r--r--tools/llvm-as/Makefile2
-rw-r--r--tools/llvm-bcanalyzer/Makefile1
-rw-r--r--tools/llvm-config/Makefile1
-rw-r--r--tools/llvm-config/llvm-config.in.in15
-rw-r--r--tools/llvm-dis/Makefile2
-rw-r--r--tools/llvm-extract/Makefile1
-rw-r--r--tools/llvm-ld/Makefile1
-rw-r--r--tools/llvm-link/Makefile1
-rw-r--r--tools/llvm-mc/AsmLexer.cpp61
-rw-r--r--tools/llvm-mc/AsmLexer.h17
-rw-r--r--tools/llvm-mc/AsmParser.cpp302
-rw-r--r--tools/llvm-mc/AsmParser.h27
-rw-r--r--tools/llvm-mc/CMakeLists.txt4
-rw-r--r--tools/llvm-mc/Makefile3
-rw-r--r--tools/llvm-mc/llvm-mc.cpp13
-rw-r--r--tools/llvm-nm/Makefile1
-rw-r--r--tools/llvm-prof/Makefile1
-rw-r--r--tools/lto/LTOCodeGenerator.cpp13
-rw-r--r--tools/lto/LTOModule.cpp16
-rw-r--r--tools/lto/Makefile1
-rw-r--r--tools/opt/Makefile1
-rw-r--r--tools/opt/opt.cpp65
-rw-r--r--unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp4
-rw-r--r--unittests/ExecutionEngine/JIT/JITTest.cpp14
-rw-r--r--unittests/Support/System.cpp16
-rw-r--r--unittests/VMCore/PassManagerTest.cpp5
-rwxr-xr-xutils/GetSourceVersion27
-rw-r--r--utils/TableGen/AsmMatcherEmitter.cpp12
-rwxr-xr-xutils/buildit/build_llvm27
-rw-r--r--utils/lit/lit/Test.py2
-rw-r--r--utils/llvm.grm1
-rwxr-xr-xutils/mkpatch4
-rw-r--r--utils/vim/llvm.vim2
473 files changed, 11300 insertions, 9062 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7063640..216e0f6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -304,6 +304,7 @@ add_subdirectory(lib/Linker)
add_subdirectory(lib/Analysis)
add_subdirectory(lib/Analysis/IPA)
add_subdirectory(lib/MC)
+add_subdirectory(lib/MC/MCParser)
add_subdirectory(test)
add_subdirectory(utils/FileCheck)
diff --git a/Makefile b/Makefile
index 2183a5b..319bdcd 100644
--- a/Makefile
+++ b/Makefile
@@ -66,7 +66,8 @@ ifeq ($(MAKECMDGOALS),tools-only)
endif
ifeq ($(MAKECMDGOALS),install-clang)
- DIRS := tools/clang/tools/driver tools/clang/lib/Headers tools/clang/docs
+ DIRS := tools/clang/tools/driver tools/clang/lib/Headers \
+ tools/clang/lib/Runtime tools/clang/docs
OPTIONAL_DIRS :=
NO_INSTALL = 1
endif
diff --git a/Makefile.rules b/Makefile.rules
index 49ecb1e..3d436c4 100644
--- a/Makefile.rules
+++ b/Makefile.rules
@@ -439,6 +439,17 @@ else
endif
endif
+ifeq ($(HOST_OS),MingW)
+ # Work around PR4957
+ CPP.Defines += -D__NO_CTYPE_INLINE
+ ifeq ($(LLVM_CROSS_COMPILING),1)
+ # Work around http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=525016
+ ifdef TOOLNAME
+ LD.Flags += -Wl,--allow-multiple-definition
+ endif
+ endif
+endif
+
CXX.Flags += -Woverloaded-virtual
CPP.BaseFlags += $(CPP.Defines)
AR.Flags := cru
@@ -457,15 +468,6 @@ ifeq ($(ARCH),Alpha)
LD.Flags += -Wl,--no-relax
endif
-ifeq ($(HOST_OS),MingW)
- ifeq ($(LLVM_CROSS_COMPILING),1)
- # Work around http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=525016
- ifdef TOOLNAME
- LD.Flags += -Wl,--allow-multiple-definition
- endif
- endif
-endif
-
ifdef ENABLE_EXPENSIVE_CHECKS
# GNU libstdc++ uses RTTI if you define _GLIBCXX_DEBUG, which we did above.
# See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40160
@@ -1351,17 +1353,17 @@ DEPEND_OPTIONS = -MMD -MP -MF "$(ObjDir)/$*.d.tmp" \
DEPEND_MOVEFILE = then $(MV) -f "$(ObjDir)/$*.d.tmp" "$(ObjDir)/$*.d"; \
else $(RM) "$(ObjDir)/$*.d.tmp"; exit 1; fi
-$(ObjDir)/%.o: %.cpp $(ObjDir)/.dir $(BUILT_SOURCES)
+$(ObjDir)/%.o: %.cpp $(ObjDir)/.dir $(BUILT_SOURCES) $(PROJ_SRC_DIR)/Makefile
$(Echo) "Compiling $*.cpp for $(BuildMode) build" $(PIC_FLAG)
$(Verb) if $(Compile.CXX) $(DEPEND_OPTIONS) $< -o $(ObjDir)/$*.o ; \
$(DEPEND_MOVEFILE)
-$(ObjDir)/%.o: %.cc $(ObjDir)/.dir $(BUILT_SOURCES)
+$(ObjDir)/%.o: %.cc $(ObjDir)/.dir $(BUILT_SOURCES) $(PROJ_SRC_DIR)/Makefile
$(Echo) "Compiling $*.cc for $(BuildMode) build" $(PIC_FLAG)
$(Verb) if $(Compile.CXX) $(DEPEND_OPTIONS) $< -o $(ObjDir)/$*.o ; \
$(DEPEND_MOVEFILE)
-$(ObjDir)/%.o: %.c $(ObjDir)/.dir $(BUILT_SOURCES)
+$(ObjDir)/%.o: %.c $(ObjDir)/.dir $(BUILT_SOURCES) $(PROJ_SRC_DIR)/Makefile
$(Echo) "Compiling $*.c for $(BuildMode) build" $(PIC_FLAG)
$(Verb) if $(Compile.C) $(DEPEND_OPTIONS) $< -o $(ObjDir)/$*.o ; \
$(DEPEND_MOVEFILE)
diff --git a/bindings/ocaml/llvm/llvm.ml b/bindings/ocaml/llvm/llvm.ml
index 37d0fd7..25e47ab 100644
--- a/bindings/ocaml/llvm/llvm.ml
+++ b/bindings/ocaml/llvm/llvm.ml
@@ -93,7 +93,6 @@ module Attribute = struct
| Noredzone
| Noimplicitfloat
| Naked
- | Inlinehint
end
module Icmp = struct
@@ -848,7 +847,7 @@ module ModuleProvider = struct
= "LLVMCreateModuleProviderForExistingModule"
external dispose : llmoduleprovider -> unit = "llvm_dispose_module_provider"
end
-
+
(*===-- Memory buffers ----------------------------------------------------===*)
diff --git a/bindings/ocaml/llvm/llvm.mli b/bindings/ocaml/llvm/llvm.mli
index a7c2bcf..c703ef7 100644
--- a/bindings/ocaml/llvm/llvm.mli
+++ b/bindings/ocaml/llvm/llvm.mli
@@ -143,7 +143,6 @@ module Attribute : sig
| Noredzone
| Noimplicitfloat
| Naked
- | Inlinehint
end
(** The predicate for an integer comparison ([icmp]) instruction.
diff --git a/bindings/ocaml/llvm/llvm_ocaml.c b/bindings/ocaml/llvm/llvm_ocaml.c
index 8868d07..6cc475d 100644
--- a/bindings/ocaml/llvm/llvm_ocaml.c
+++ b/bindings/ocaml/llvm/llvm_ocaml.c
@@ -112,9 +112,9 @@ CAMLprim LLVMContextRef llvm_global_context(value Unit) {
/*===-- Modules -----------------------------------------------------------===*/
-/* string -> llmodule */
-CAMLprim LLVMModuleRef llvm_create_module(value ModuleID) {
- return LLVMModuleCreateWithName(String_val(ModuleID));
+/* llcontext -> string -> llmodule */
+CAMLprim LLVMModuleRef llvm_create_module(LLVMContextRef C, value ModuleID) {
+ return LLVMModuleCreateWithNameInContext(String_val(ModuleID), C);
}
/* llmodule -> unit */
diff --git a/cmake/modules/LLVMLibDeps.cmake b/cmake/modules/LLVMLibDeps.cmake
index bc2f45b..e1c470f 100644
--- a/cmake/modules/LLVMLibDeps.cmake
+++ b/cmake/modules/LLVMLibDeps.cmake
@@ -1,4 +1,4 @@
-set(MSVC_LIB_DEPS_LLVMARMAsmParser LLVMARMInfo LLVMMC)
+set(MSVC_LIB_DEPS_LLVMARMAsmParser LLVMARMInfo LLVMMCParser LLVMSupport)
set(MSVC_LIB_DEPS_LLVMARMAsmPrinter LLVMARMCodeGen LLVMARMInfo LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget)
set(MSVC_LIB_DEPS_LLVMARMCodeGen LLVMARMInfo LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget)
set(MSVC_LIB_DEPS_LLVMARMInfo LLVMSupport)
@@ -14,7 +14,7 @@ set(MSVC_LIB_DEPS_LLVMBitWriter LLVMCore LLVMSupport LLVMSystem)
set(MSVC_LIB_DEPS_LLVMBlackfinAsmPrinter LLVMAsmPrinter LLVMBlackfinInfo LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget)
set(MSVC_LIB_DEPS_LLVMBlackfinCodeGen LLVMBlackfinInfo LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget)
set(MSVC_LIB_DEPS_LLVMBlackfinInfo LLVMSupport)
-set(MSVC_LIB_DEPS_LLVMCBackend LLVMAnalysis LLVMCBackendInfo LLVMCodeGen LLVMCore LLVMScalarOpts LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils LLVMipa)
+set(MSVC_LIB_DEPS_LLVMCBackend LLVMAnalysis LLVMCBackendInfo LLVMCodeGen LLVMCore LLVMMC LLVMScalarOpts LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils LLVMipa)
set(MSVC_LIB_DEPS_LLVMCBackendInfo LLVMSupport)
set(MSVC_LIB_DEPS_LLVMCellSPUAsmPrinter LLVMAsmPrinter LLVMCellSPUInfo LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget)
set(MSVC_LIB_DEPS_LLVMCellSPUCodeGen LLVMCellSPUInfo LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget)
@@ -27,9 +27,10 @@ set(MSVC_LIB_DEPS_LLVMExecutionEngine LLVMCore LLVMSupport LLVMSystem LLVMTarget
set(MSVC_LIB_DEPS_LLVMInstCombine LLVMAnalysis LLVMCore LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils)
set(MSVC_LIB_DEPS_LLVMInstrumentation LLVMAnalysis LLVMCore LLVMSupport LLVMSystem LLVMTransformUtils)
set(MSVC_LIB_DEPS_LLVMInterpreter LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMSupport LLVMSystem LLVMTarget)
-set(MSVC_LIB_DEPS_LLVMJIT LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMMC LLVMSupport LLVMSystem LLVMTarget)
+set(MSVC_LIB_DEPS_LLVMJIT LLVMAnalysis LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMMC LLVMSupport LLVMSystem LLVMTarget)
set(MSVC_LIB_DEPS_LLVMLinker LLVMArchive LLVMBitReader LLVMCore LLVMSupport LLVMSystem)
set(MSVC_LIB_DEPS_LLVMMC LLVMSupport LLVMSystem)
+set(MSVC_LIB_DEPS_LLVMMCParser LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMMSIL LLVMAnalysis LLVMCodeGen LLVMCore LLVMMSILInfo LLVMScalarOpts LLVMSupport LLVMTarget LLVMTransformUtils LLVMipa)
set(MSVC_LIB_DEPS_LLVMMSILInfo LLVMSupport)
set(MSVC_LIB_DEPS_LLVMMSP430AsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMMSP430Info LLVMSupport LLVMSystem LLVMTarget)
@@ -56,8 +57,8 @@ set(MSVC_LIB_DEPS_LLVMSystemZCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDA
set(MSVC_LIB_DEPS_LLVMSystemZInfo LLVMSupport)
set(MSVC_LIB_DEPS_LLVMTarget LLVMCore LLVMMC LLVMSupport)
set(MSVC_LIB_DEPS_LLVMTransformUtils LLVMAnalysis LLVMCore LLVMSupport LLVMSystem LLVMTarget LLVMipa)
-set(MSVC_LIB_DEPS_LLVMX86AsmParser LLVMMC LLVMX86Info)
-set(MSVC_LIB_DEPS_LLVMX86AsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget LLVMX86CodeGen LLVMX86Info)
+set(MSVC_LIB_DEPS_LLVMX86AsmParser LLVMMC LLVMMCParser LLVMSupport LLVMX86Info)
+set(MSVC_LIB_DEPS_LLVMX86AsmPrinter LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget LLVMX86CodeGen LLVMX86Info)
set(MSVC_LIB_DEPS_LLVMX86CodeGen LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget LLVMX86Info)
set(MSVC_LIB_DEPS_LLVMX86Disassembler LLVMMC LLVMSupport LLVMX86Info)
set(MSVC_LIB_DEPS_LLVMX86Info LLVMSupport)
diff --git a/docs/BitCodeFormat.html b/docs/BitCodeFormat.html
index 7a46d90..7413752 100644
--- a/docs/BitCodeFormat.html
+++ b/docs/BitCodeFormat.html
@@ -138,8 +138,7 @@ bitcode, while application-specific programs will want to look at all four.</p>
A bitstream literally consists of a stream of bits, which are read in order
starting with the least significant bit of each byte. The stream is made up of a
number of primitive values that encode a stream of unsigned integer values.
-These
-integers are are encoded in two ways: either as <a href="#fixedwidth">Fixed
+These integers are encoded in two ways: either as <a href="#fixedwidth">Fixed
Width Integers</a> or as <a href="#variablewidth">Variable Width
Integers</a>.
</p>
@@ -1158,7 +1157,7 @@ fields of <tt>FUNCTION</tt> records.</p>
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.org">The LLVM Compiler Infrastructure</a><br>
-Last modified: $Date: 2009-10-29 05:25:46 +0100 (Thu, 29 Oct 2009) $
+Last modified: $Date: 2010-01-20 18:53:51 +0100 (Wed, 20 Jan 2010) $
</address>
</body>
</html>
diff --git a/docs/LangRef.html b/docs/LangRef.html
index 6ea0ead..cbb7d56 100644
--- a/docs/LangRef.html
+++ b/docs/LangRef.html
@@ -924,9 +924,9 @@ define [<a href="#linkage">linkage</a>] [<a href="#visibility">visibility</a>]
<div class="doc_text">
-<p>Named metadata is a collection of metadata. <a href="#metadata"> Metadata </a>
- node and null are the only valid named metadata operands.
- Metadata strings are not allowed as an named metadata operand.</p>
+<p>Named metadata is a collection of metadata. <a href="#metadata">Metadata
+ nodes</a> (but not metadata strings) and null are the only valid operands for
+ a named metadata.</p>
<h5>Syntax:</h5>
<div class="doc_code">
@@ -1083,11 +1083,6 @@ define void @f() optsize { ... }
function into callers whenever possible, ignoring any active inlining size
threshold for this caller.</dd>
- <dt><tt><b>inlinehint</b></tt></dt>
- <dd>This attribute indicates that the source code contained a hint that inlining
- this function is desirable (such as the "inline" keyword in C/C++). It
- is just a hint; it imposes no requirements on the inliner.</dd>
-
<dt><tt><b>noinline</b></tt></dt>
<dd>This attribute indicates that the inliner should never inline this
function in any situation. This attribute may not be used together with
@@ -2340,41 +2335,6 @@ has undefined behavior.</p>
</div>
-<!-- ======================================================================= -->
-<div class="doc_subsection"><a name="metadata">Metadata Nodes and Metadata Strings</a>
-</div>
-
-<div class="doc_text">
-
-<p>Metadata provides a way to attach arbitrary data to the instruction
- stream without affecting the behaviour of the program. There are two
- metadata primitives, strings and nodes. All metadata has the
- <tt>metadata</tt> type and is identified in syntax by a preceding exclamation
- point ('<tt>!</tt>').</p>
-
-<p>A metadata string is a string surrounded by double quotes. It can contain
- any character by escaping non-printable characters with "\xx" where "xx" is
- the two digit hex code. For example: "<tt>!"test\00"</tt>".</p>
-
-<p>Metadata nodes are represented with notation similar to structure constants
- (a comma separated list of elements, surrounded by braces and preceded by an
- exclamation point). For example: "<tt>!{ metadata !"test\00", i32
- 10}</tt>".</p>
-
-<p>A metadata node will attempt to track changes to the values it holds. In the
- event that a value is deleted, it will be replaced with a typeless
- "<tt>null</tt>", such as "<tt>metadata !{null, i32 10}</tt>".</p>
-
-<p>A <a href="#namedmetadatastructure">named metadata</a> is a collection of
- metadata nodes. For example: "<tt>!foo = metadata !{!4, !3}</tt>".
-
-<p>Optimizations may rely on metadata to provide additional information about
- the program that isn't available in the instructions, or that isn't easily
- computable. Similarly, the code generator may expect a certain metadata
- format to be used to express debugging information.</p>
-
-</div>
-
<!-- *********************************************************************** -->
<div class="doc_section"> <a name="othervalues">Other Values</a> </div>
<!-- *********************************************************************** -->
@@ -2444,6 +2404,35 @@ call void asm alignstack "eieio", ""()
</div>
+<!-- ======================================================================= -->
+<div class="doc_subsection"><a name="metadata">Metadata Nodes and Metadata
+ Strings</a>
+</div>
+
+<div class="doc_text">
+
+<p>LLVM IR allows metadata to be attached to instructions in the program that
+ can convey extra information about the code to the optimizers and code
+ generator. One example application of metadata is source-level debug
+ information. There are two metadata primitives: strings and nodes. All
+ metadata has the <tt>metadata</tt> type and is identified in syntax by a
+ preceding exclamation point ('<tt>!</tt>').</p>
+
+<p>A metadata string is a string surrounded by double quotes. It can contain
+ any character by escaping non-printable characters with "\xx" where "xx" is
+ the two digit hex code. For example: "<tt>!"test\00"</tt>".</p>
+
+<p>Metadata nodes are represented with notation similar to structure constants
+ (a comma separated list of elements, surrounded by braces and preceded by an
+ exclamation point). For example: "<tt>!{ metadata !"test\00", i32
+ 10}</tt>". Metadata nodes can have any values as their operand.</p>
+
+<p>A <a href="#namedmetadatastructure">named metadata</a> is a collection of
+ metadata nodes, which can be looked up in the module symbol table. For
+ example: "<tt>!foo = metadata !{!4, !3}</tt>".
+
+</div>
+
<!-- *********************************************************************** -->
<div class="doc_section">
@@ -2840,6 +2829,9 @@ IfUnequal:
block to the "normal" label. If the callee unwinds then no return value is
available.</p>
+<p>Note that the code generator does not yet completely support unwind, and
+that the invoke/unwind semantics are likely to change in future versions.</p>
+
<h5>Example:</h5>
<pre>
%retval = invoke i32 @Test(i32 15) to label %Continue
@@ -2876,6 +2868,9 @@ Instruction</a> </div>
specified by the <tt>invoke</tt> instruction. If there is no <tt>invoke</tt>
instruction in the dynamic call chain, undefined behavior results.</p>
+<p>Note that the code generator does not yet completely support unwind, and
+that the invoke/unwind semantics are likely to change in future versions.</p>
+
</div>
<!-- _______________________________________________________________________ -->
@@ -7350,7 +7345,7 @@ LLVM</a>.</p>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2010-01-11 20:35:55 +0100 (Mon, 11 Jan 2010) $
+ Last modified: $Date: 2010-01-15 22:50:19 +0100 (Fri, 15 Jan 2010) $
</address>
</body>
diff --git a/docs/ReleaseNotes.html b/docs/ReleaseNotes.html
index aff0836..03a3545 100644
--- a/docs/ReleaseNotes.html
+++ b/docs/ReleaseNotes.html
@@ -59,6 +59,7 @@ Almost dead code.
lib/Transforms/IPO/MergeFunctions.cpp => consider for 2.8.
llvm/Analysis/PointerTracking.h => Edwin wants this, consider for 2.8.
ABCD, SCCVN, GEPSplitterPass
+ MSIL backend?
-->
@@ -1349,7 +1350,7 @@ lists</a>.</p>
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
- Last modified: $Date: 2010-01-09 23:30:40 +0100 (Sat, 09 Jan 2010) $
+ Last modified: $Date: 2010-01-16 22:25:13 +0100 (Sat, 16 Jan 2010) $
</address>
</body>
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h
index 6879205..d57c250 100644
--- a/include/llvm-c/Core.h
+++ b/include/llvm-c/Core.h
@@ -117,8 +117,7 @@ typedef enum {
LLVMNoCaptureAttribute = 1<<21,
LLVMNoRedZoneAttribute = 1<<22,
LLVMNoImplicitFloatAttribute = 1<<23,
- LLVMNakedAttribute = 1<<24,
- LLVMInlineHintAttribute = 1<<25
+ LLVMNakedAttribute = 1<<24
} LLVMAttribute;
typedef enum {
@@ -1008,7 +1007,7 @@ namespace llvm {
\
template<typename T> \
inline T *unwrap(ref P) { \
- T *Q = dynamic_cast<T*>(unwrap(P)); \
+ T *Q = (T*)unwrap(P); \
assert(Q && "Invalid cast!"); \
return Q; \
}
diff --git a/include/llvm/ADT/DenseMapInfo.h b/include/llvm/ADT/DenseMapInfo.h
index 6b494ef..41197a1 100644
--- a/include/llvm/ADT/DenseMapInfo.h
+++ b/include/llvm/ADT/DenseMapInfo.h
@@ -92,6 +92,19 @@ template<> struct DenseMapInfo<unsigned long long> {
}
};
+// Provide DenseMapInfo for long longs.
+template<> struct DenseMapInfo<long long> {
+ static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; }
+ static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; }
+ static unsigned getHashValue(const long long& Val) {
+ return (unsigned)(Val * 37LL);
+ }
+ static bool isEqual(const long long& LHS,
+ const long long& RHS) {
+ return LHS == RHS;
+ }
+};
+
// Provide DenseMapInfo for all pairs whose members have info.
template<typename T, typename U>
struct DenseMapInfo<std::pair<T, U> > {
diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h
index fc9fe8b..1b3f1a9 100644
--- a/include/llvm/ADT/ImmutableMap.h
+++ b/include/llvm/ADT/ImmutableMap.h
@@ -217,7 +217,7 @@ public:
// Utility methods.
//===--------------------------------------------------===//
- inline unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
+ unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
static inline void Profile(FoldingSetNodeID& ID, const ImmutableMap& M) {
ID.AddPointer(M.Root);
diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h
index 676a198..ac06a40 100644
--- a/include/llvm/ADT/ImmutableSet.h
+++ b/include/llvm/ADT/ImmutableSet.h
@@ -51,13 +51,11 @@ public:
/// getLeft - Returns a pointer to the left subtree. This value
/// is NULL if there is no left subtree.
- ImutAVLTree *getLeft() const {
- return reinterpret_cast<ImutAVLTree*>(Left & ~LeftFlags);
- }
+ ImutAVLTree *getLeft() const { return Left; }
/// getRight - Returns a pointer to the right subtree. This value is
/// NULL if there is no right subtree.
- ImutAVLTree* getRight() const { return Right; }
+ ImutAVLTree *getRight() const { return Right; }
/// getHeight - Returns the height of the tree. A tree with no subtrees
/// has a height of 1.
@@ -190,23 +188,22 @@ public:
unsigned HL = getLeft() ? getLeft()->verify() : 0;
unsigned HR = getRight() ? getRight()->verify() : 0;
- assert (getHeight() == ( HL > HR ? HL : HR ) + 1
- && "Height calculation wrong.");
-
- assert ((HL > HR ? HL-HR : HR-HL) <= 2
- && "Balancing invariant violated.");
+ assert(getHeight() == ( HL > HR ? HL : HR ) + 1
+ && "Height calculation wrong");
+ assert((HL > HR ? HL-HR : HR-HL) <= 2
+ && "Balancing invariant violated");
- assert (!getLeft()
- || ImutInfo::isLess(ImutInfo::KeyOfValue(getLeft()->getValue()),
- ImutInfo::KeyOfValue(getValue()))
- && "Value in left child is not less that current value.");
+ assert(!getLeft()
+ || ImutInfo::isLess(ImutInfo::KeyOfValue(getLeft()->getValue()),
+ ImutInfo::KeyOfValue(getValue()))
+ && "Value in left child is not less that current value");
- assert (!getRight()
- || ImutInfo::isLess(ImutInfo::KeyOfValue(getValue()),
- ImutInfo::KeyOfValue(getRight()->getValue()))
- && "Current value is not less that value of right child.");
+ assert(!getRight()
+ || ImutInfo::isLess(ImutInfo::KeyOfValue(getValue()),
+ ImutInfo::KeyOfValue(getRight()->getValue()))
+ && "Current value is not less that value of right child");
return getHeight();
}
@@ -221,9 +218,11 @@ public:
//===----------------------------------------------------===//
private:
- uintptr_t Left;
+ ImutAVLTree* Left;
ImutAVLTree* Right;
- unsigned Height;
+ unsigned Height : 28;
+ unsigned Mutable : 1;
+ unsigned CachedDigest : 1;
value_type Value;
uint32_t Digest;
@@ -232,15 +231,12 @@ private:
//===----------------------------------------------------===//
private:
-
- enum { Mutable = 0x1, NoCachedDigest = 0x2, LeftFlags = 0x3 };
-
/// ImutAVLTree - Internal constructor that is only called by
/// ImutAVLFactory.
- ImutAVLTree(ImutAVLTree* l, ImutAVLTree* r, value_type_ref v, unsigned height)
- : Left(reinterpret_cast<uintptr_t>(l) | (Mutable | NoCachedDigest)),
- Right(r), Height(height), Value(v), Digest(0) {}
-
+ ImutAVLTree(ImutAVLTree* l, ImutAVLTree* r, value_type_ref v,
+ unsigned height)
+ : Left(l), Right(r), Height(height), Mutable(true), CachedDigest(false),
+ Value(v), Digest(0) {}
/// isMutable - Returns true if the left and right subtree references
/// (as well as height) can be changed. If this method returns false,
@@ -248,11 +244,11 @@ private:
/// object should always have this method return true. Further, if this
/// method returns false for an instance of ImutAVLTree, all subtrees
/// will also have this method return false. The converse is not true.
- bool isMutable() const { return Left & Mutable; }
+ bool isMutable() const { return Mutable; }
/// hasCachedDigest - Returns true if the digest for this tree is cached.
/// This can only be true if the tree is immutable.
- bool hasCachedDigest() const { return !(Left & NoCachedDigest); }
+ bool hasCachedDigest() const { return CachedDigest; }
//===----------------------------------------------------===//
// Mutating operations. A tree root can be manipulated as
@@ -269,13 +265,13 @@ private:
/// it is an error to call setLeft(), setRight(), and setHeight().
void MarkImmutable() {
assert(isMutable() && "Mutable flag already removed.");
- Left &= ~Mutable;
+ Mutable = false;
}
/// MarkedCachedDigest - Clears the NoCachedDigest flag for a tree.
void MarkedCachedDigest() {
assert(!hasCachedDigest() && "NoCachedDigest flag already removed.");
- Left &= ~NoCachedDigest;
+ CachedDigest = true;
}
/// setLeft - Changes the reference of the left subtree. Used internally
@@ -283,7 +279,8 @@ private:
void setLeft(ImutAVLTree* NewLeft) {
assert(isMutable() &&
"Only a mutable tree can have its left subtree changed.");
- Left = reinterpret_cast<uintptr_t>(NewLeft) | LeftFlags;
+ Left = NewLeft;
+ CachedDigest = false;
}
/// setRight - Changes the reference of the right subtree. Used internally
@@ -293,9 +290,7 @@ private:
"Only a mutable tree can have its right subtree changed.");
Right = NewRight;
- // Set the NoCachedDigest flag.
- Left = Left | NoCachedDigest;
-
+ CachedDigest = false;
}
/// setHeight - Changes the height of the tree. Used internally by
@@ -397,7 +392,7 @@ public:
private:
bool isEmpty(TreeTy* T) const { return !T; }
- unsigned Height(TreeTy* T) const { return T ? T->getHeight() : 0; }
+ unsigned Height(TreeTy* T) const { return T ? T->getHeight() : 0; }
TreeTy* Left(TreeTy* T) const { return T->getLeft(); }
TreeTy* Right(TreeTy* T) const { return T->getRight(); }
value_type_ref Value(TreeTy* T) const { return T->Value; }
@@ -405,7 +400,7 @@ private:
unsigned IncrementHeight(TreeTy* L, TreeTy* R) const {
unsigned hl = Height(L);
unsigned hr = Height(R);
- return ( hl > hr ? hl : hr ) + 1;
+ return (hl > hr ? hl : hr) + 1;
}
static bool CompareTreeWithSection(TreeTy* T,
@@ -434,17 +429,17 @@ private:
TreeTy* CreateNode(TreeTy* L, value_type_ref V, TreeTy* R) {
BumpPtrAllocator& A = getAllocator();
TreeTy* T = (TreeTy*) A.Allocate<TreeTy>();
- new (T) TreeTy(L,R,V,IncrementHeight(L,R));
+ new (T) TreeTy(L, R, V, IncrementHeight(L,R));
return T;
}
TreeTy* CreateNode(TreeTy* L, TreeTy* OldTree, TreeTy* R) {
- assert (!isEmpty(OldTree));
+ assert(!isEmpty(OldTree));
if (OldTree->isMutable()) {
OldTree->setLeft(L);
OldTree->setRight(R);
- OldTree->setHeight(IncrementHeight(L,R));
+ OldTree->setHeight(IncrementHeight(L, R));
return OldTree;
}
else
@@ -459,8 +454,7 @@ private:
unsigned hr = Height(R);
if (hl > hr + 2) {
- assert (!isEmpty(L) &&
- "Left tree cannot be empty to have a height >= 2.");
+ assert(!isEmpty(L) && "Left tree cannot be empty to have a height >= 2");
TreeTy* LL = Left(L);
TreeTy* LR = Right(L);
@@ -468,8 +462,7 @@ private:
if (Height(LL) >= Height(LR))
return CreateNode(LL, L, CreateNode(LR,V,R));
- assert (!isEmpty(LR) &&
- "LR cannot be empty because it has a height >= 1.");
+ assert(!isEmpty(LR) && "LR cannot be empty because it has a height >= 1");
TreeTy* LRL = Left(LR);
TreeTy* LRR = Right(LR);
@@ -477,8 +470,7 @@ private:
return CreateNode(CreateNode(LL,L,LRL), LR, CreateNode(LRR,V,R));
}
else if (hr > hl + 2) {
- assert (!isEmpty(R) &&
- "Right tree cannot be empty to have a height >= 2.");
+ assert(!isEmpty(R) && "Right tree cannot be empty to have a height >= 2");
TreeTy* RL = Left(R);
TreeTy* RR = Right(R);
@@ -486,8 +478,7 @@ private:
if (Height(RR) >= Height(RL))
return CreateNode(CreateNode(L,V,RL), R, RR);
- assert (!isEmpty(RL) &&
- "RL cannot be empty because it has a height >= 1.");
+ assert(!isEmpty(RL) && "RL cannot be empty because it has a height >= 1");
TreeTy* RLL = Left(RL);
TreeTy* RLR = Right(RL);
@@ -505,7 +496,7 @@ private:
if (isEmpty(T))
return CreateNode(T, V, T);
- assert (!T->isMutable());
+ assert(!T->isMutable());
key_type_ref K = ImutInfo::KeyOfValue(V);
key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T));
@@ -526,7 +517,7 @@ private:
if (isEmpty(T))
return T;
- assert (!T->isMutable());
+ assert(!T->isMutable());
key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T));
@@ -548,7 +539,7 @@ private:
}
TreeTy* RemoveMinBinding(TreeTy* T, TreeTy*& NodeRemoved) {
- assert (!isEmpty(T));
+ assert(!isEmpty(T));
if (isEmpty(Left(T))) {
NodeRemoved = T;
@@ -641,12 +632,12 @@ public:
}
TreeTy* operator*() const {
- assert (!stack.empty());
+ assert(!stack.empty());
return reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
}
uintptr_t getVisitState() {
- assert (!stack.empty());
+ assert(!stack.empty());
return stack.back() & Flags;
}
@@ -658,7 +649,7 @@ public:
}
void SkipToParent() {
- assert (!stack.empty());
+ assert(!stack.empty());
stack.pop_back();
if (stack.empty())
@@ -672,7 +663,7 @@ public:
stack.back() |= VisitedRight;
break;
default:
- assert (false && "Unreachable.");
+ assert(false && "Unreachable.");
}
}
@@ -690,10 +681,10 @@ public:
inline bool operator!=(const _Self& x) const { return !operator==(x); }
_Self& operator++() {
- assert (!stack.empty());
+ assert(!stack.empty());
TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
- assert (Current);
+ assert(Current);
switch (getVisitState()) {
case VisitedNone:
@@ -717,17 +708,17 @@ public:
break;
default:
- assert (false && "Unreachable.");
+ assert(false && "Unreachable.");
}
return *this;
}
_Self& operator--() {
- assert (!stack.empty());
+ assert(!stack.empty());
TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
- assert (Current);
+ assert(Current);
switch (getVisitState()) {
case VisitedNone:
@@ -752,7 +743,7 @@ public:
break;
default:
- assert (false && "Unreachable.");
+ assert(false && "Unreachable.");
}
return *this;
@@ -1051,7 +1042,7 @@ public:
// Utility methods.
//===--------------------------------------------------===//
- inline unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
+ unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
static inline void Profile(FoldingSetNodeID& ID, const ImmutableSet& S) {
ID.AddPointer(S.Root);
diff --git a/include/llvm/Analysis/DOTGraphTraitsPass.h b/include/llvm/Analysis/DOTGraphTraitsPass.h
new file mode 100644
index 0000000..4828eba
--- /dev/null
+++ b/include/llvm/Analysis/DOTGraphTraitsPass.h
@@ -0,0 +1,83 @@
+//===-- DOTGraphTraitsPass.h - Print/View dotty graphs-----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Templates to create dotty viewer and printer passes for GraphTraits graphs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H
+#define LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H
+
+#include "llvm/Pass.h"
+#include "llvm/Analysis/CFGPrinter.h"
+
+namespace llvm {
+template <class Analysis, bool Simple>
+struct DOTGraphTraitsViewer : public FunctionPass {
+ std::string Name;
+
+ DOTGraphTraitsViewer(std::string GraphName, const void *ID) : FunctionPass(ID) {
+ Name = GraphName;
+ }
+
+ virtual bool runOnFunction(Function &F) {
+ Analysis *Graph;
+ std::string Title, GraphName;
+ Graph = &getAnalysis<Analysis>();
+ GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
+ Title = GraphName + " for '" + F.getNameStr() + "' function";
+ ViewGraph(Graph, Name, Simple, Title);
+
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<Analysis>();
+ }
+};
+
+template <class Analysis, bool Simple>
+struct DOTGraphTraitsPrinter : public FunctionPass {
+
+ std::string Name;
+
+ DOTGraphTraitsPrinter(std::string GraphName, const void *ID)
+ : FunctionPass(ID) {
+ Name = GraphName;
+ }
+
+ virtual bool runOnFunction(Function &F) {
+ Analysis *Graph;
+ std::string Filename = Name + "." + F.getNameStr() + ".dot";
+ errs() << "Writing '" << Filename << "'...";
+
+ std::string ErrorInfo;
+ raw_fd_ostream File(Filename.c_str(), ErrorInfo);
+ Graph = &getAnalysis<Analysis>();
+
+ std::string Title, GraphName;
+ GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
+ Title = GraphName + " for '" + F.getNameStr() + "' function";
+
+ if (ErrorInfo.empty())
+ WriteGraph(File, Graph, Simple, Name, Title);
+ else
+ errs() << " error opening file for writing!";
+ errs() << "\n";
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<Analysis>();
+ }
+};
+}
+#endif
diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h
index cc9514c..150d3ee 100644
--- a/include/llvm/Analysis/DebugInfo.h
+++ b/include/llvm/Analysis/DebugInfo.h
@@ -475,7 +475,7 @@ namespace llvm {
/// is not associated with any DWARF tag.
class DILocation : public DIDescriptor {
public:
- explicit DILocation(MDNode *N) : DIDescriptor(N) { ; }
+ explicit DILocation(MDNode *N) : DIDescriptor(N) { }
unsigned getLineNumber() const { return getUnsignedField(0); }
unsigned getColumnNumber() const { return getUnsignedField(1); }
@@ -587,7 +587,7 @@ namespace llvm {
StringRef DisplayName,
StringRef LinkageName,
DICompileUnit CompileUnit, unsigned LineNo,
- DIType Type, bool isLocalToUnit,
+ DIType Ty, bool isLocalToUnit,
bool isDefinition,
unsigned VK = 0,
unsigned VIndex = 0,
@@ -603,21 +603,21 @@ namespace llvm {
StringRef DisplayName,
StringRef LinkageName,
DICompileUnit CompileUnit,
- unsigned LineNo, DIType Type, bool isLocalToUnit,
+ unsigned LineNo, DIType Ty, bool isLocalToUnit,
bool isDefinition, llvm::GlobalVariable *GV);
/// CreateVariable - Create a new descriptor for the specified variable.
DIVariable CreateVariable(unsigned Tag, DIDescriptor Context,
StringRef Name,
DICompileUnit CompileUnit, unsigned LineNo,
- DIType Type);
+ DIType Ty);
/// CreateComplexVariable - Create a new descriptor for the specified
/// variable which has a complex address expression for its address.
DIVariable CreateComplexVariable(unsigned Tag, DIDescriptor Context,
const std::string &Name,
DICompileUnit CompileUnit, unsigned LineNo,
- DIType Type,
+ DIType Ty,
SmallVector<Value *, 9> &addr);
/// CreateLexicalBlock - This creates a descriptor for a lexical block
@@ -656,13 +656,6 @@ namespace llvm {
Constant *GetTagConstant(unsigned TAG);
};
- /// Finds the dbg.declare intrinsic corresponding to this value if any.
- /// It looks through pointer casts too.
- const DbgDeclareInst *findDbgDeclare(const Value *V);
-
- /// Find the debug info descriptor corresponding to this global variable.
- Value *findDbgGlobalDeclare(GlobalVariable *V);
-
bool getLocationInfo(const Value *V, std::string &DisplayName,
std::string &Type, unsigned &LineNo, std::string &File,
std::string &Dir);
diff --git a/include/llvm/Analysis/DominatorInternals.h b/include/llvm/Analysis/DominatorInternals.h
index 5ecb348..8cea96d 100644
--- a/include/llvm/Analysis/DominatorInternals.h
+++ b/include/llvm/Analysis/DominatorInternals.h
@@ -262,29 +262,17 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
DT.Info[W];
// Step #2: Calculate the semidominators of all vertices
- bool HasChildOutsideDFS = false;
// initialize the semi dominator to point to the parent node
WInfo.Semi = WInfo.Parent;
for (typename GraphTraits<Inverse<NodeT> >::ChildIteratorType CI =
GraphTraits<Inverse<NodeT> >::child_begin(W),
- E = GraphTraits<Inverse<NodeT> >::child_end(W); CI != E; ++CI) {
+ E = GraphTraits<Inverse<NodeT> >::child_end(W); CI != E; ++CI)
if (DT.Info.count(*CI)) { // Only if this predecessor is reachable!
unsigned SemiU = DT.Info[Eval<GraphT>(DT, *CI)].Semi;
if (SemiU < WInfo.Semi)
WInfo.Semi = SemiU;
}
- else {
- // if the child has no DFS number it is not post-dominated by any exit,
- // and so is the current block.
- HasChildOutsideDFS = true;
- }
- }
-
- // if some child has no DFS number it is not post-dominated by any exit,
- // and so is the current block.
- if (DT.isPostDominator() && HasChildOutsideDFS)
- WInfo.Semi = 0;
DT.Info[DT.Vertex[WInfo.Semi]].Bucket.push_back(W);
diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h
index fcd9caa..50f7d45 100644
--- a/include/llvm/Analysis/IVUsers.h
+++ b/include/llvm/Analysis/IVUsers.h
@@ -212,6 +212,11 @@ public:
/// value of the OperandValToReplace of the given IVStrideUse.
const SCEV *getReplacementExpr(const IVStrideUse &U) const;
+ /// getCanonicalExpr - Return a SCEV expression which computes the
+ /// value of the SCEV of the given IVStrideUse, ignoring the
+ /// isUseOfPostIncrementedValue flag.
+ const SCEV *getCanonicalExpr(const IVStrideUse &U) const;
+
void print(raw_ostream &OS, const Module* = 0) const;
/// dump - This method is used for debugging.
diff --git a/include/llvm/Analysis/LoopPass.h b/include/llvm/Analysis/LoopPass.h
index 2dceccb..10ff103 100644
--- a/include/llvm/Analysis/LoopPass.h
+++ b/include/llvm/Analysis/LoopPass.h
@@ -28,8 +28,8 @@ class PMStack;
class LoopPass : public Pass {
public:
- explicit LoopPass(intptr_t pid) : Pass(pid) {}
- explicit LoopPass(void *pid) : Pass(pid) {}
+ explicit LoopPass(intptr_t pid) : Pass(PT_Loop, pid) {}
+ explicit LoopPass(void *pid) : Pass(PT_Loop, pid) {}
// runOnLoop - This method should be implemented by the subclass to perform
// whatever action is necessary for the specified Loop.
@@ -94,6 +94,9 @@ public:
return "Loop Pass Manager";
}
+ virtual PMDataManager *getAsPMDataManager() { return this; }
+ virtual Pass *getAsPass() { return this; }
+
/// Print passes managed by this manager
void dumpPassStructure(unsigned Offset);
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
index 6f57c74..e281971 100644
--- a/include/llvm/Analysis/ScalarEvolution.h
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -167,7 +167,7 @@ namespace llvm {
};
friend class SCEVCallbackVH;
- friend struct SCEVExpander;
+ friend class SCEVExpander;
/// F - The function we are analyzing.
///
@@ -181,6 +181,10 @@ namespace llvm {
///
TargetData *TD;
+ /// DT - The dominator tree.
+ ///
+ DominatorTree *DT;
+
/// CouldNotCompute - This SCEV is used to represent unknown trip
/// counts and things.
SCEVCouldNotCompute CouldNotCompute;
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h
index bbdd043..01df503 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpander.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpander.h
@@ -26,19 +26,47 @@ namespace llvm {
/// Clients should create an instance of this class when rewriting is needed,
/// and destroy it when finished to allow the release of the associated
/// memory.
- struct SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
+ class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
+ public:
ScalarEvolution &SE;
+
+ private:
std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> >
InsertedExpressions;
std::set<Value*> InsertedValues;
+ /// PostIncLoop - When non-null, expanded addrecs referring to the given
+ /// loop expanded in post-inc mode. For example, expanding {1,+,1}<L> in
+ /// post-inc mode returns the add instruction that adds one to the phi
+ /// for {0,+,1}<L>, as opposed to a new phi starting at 1. This is only
+ /// supported in non-canonical mode.
+ const Loop *PostIncLoop;
+
+ /// IVIncInsertPos - When this is non-null, addrecs expanded in the
+ /// loop it indicates should be inserted with increments at
+ /// IVIncInsertPos.
+ const Loop *IVIncInsertLoop;
+
+ /// IVIncInsertPos - When expanding addrecs in the IVIncInsertLoop loop,
+ /// insert the IV increment at this position.
+ Instruction *IVIncInsertPos;
+
+ /// CanonicalMode - When true, expressions are expanded in "canonical"
+ /// form. In particular, addrecs are expanded as arithmetic based on
+ /// a canonical induction variable. When false, expression are expanded
+ /// in a more literal form.
+ bool CanonicalMode;
+
+ protected:
typedef IRBuilder<true, TargetFolder> BuilderType;
BuilderType Builder;
friend struct SCEVVisitor<SCEVExpander, Value*>;
public:
+ /// SCEVExpander - Construct a SCEVExpander in "canonical" mode.
explicit SCEVExpander(ScalarEvolution &se)
- : SE(se), Builder(se.getContext(), TargetFolder(se.TD)) {}
+ : SE(se), PostIncLoop(0), IVIncInsertLoop(0), CanonicalMode(true),
+ Builder(se.getContext(), TargetFolder(se.TD)) {}
/// clear - Erase the contents of the InsertedExpressions map so that users
/// trying to expand the same expression into multiple BasicBlocks or
@@ -54,11 +82,36 @@ namespace llvm {
/// expandCodeFor - Insert code to directly compute the specified SCEV
/// expression into the program. The inserted code is inserted into the
/// specified block.
- Value *expandCodeFor(const SCEV *SH, const Type *Ty, Instruction *IP) {
+ Value *expandCodeFor(const SCEV *SH, const Type *Ty, Instruction *I) {
+ BasicBlock::iterator IP = I;
+ while (isInsertedInstruction(IP)) ++IP;
Builder.SetInsertPoint(IP->getParent(), IP);
return expandCodeFor(SH, Ty);
}
+ /// setIVIncInsertPos - Set the current IV increment loop and position.
+ void setIVIncInsertPos(const Loop *L, Instruction *Pos) {
+ assert(!CanonicalMode &&
+ "IV increment positions are not supported in CanonicalMode");
+ IVIncInsertLoop = L;
+ IVIncInsertPos = Pos;
+ }
+
+ /// setPostInc - If L is non-null, enable post-inc expansion for addrecs
+ /// referring to the given loop. If L is null, disable post-inc expansion
+ /// completely. Post-inc expansion is only supported in non-canonical
+ /// mode.
+ void setPostInc(const Loop *L) {
+ assert(!CanonicalMode &&
+ "Post-inc expansion is not supported in CanonicalMode");
+ PostIncLoop = L;
+ }
+
+ /// disableCanonicalMode - Disable the behavior of expanding expressions in
+ /// canonical form rather than in a more literal form. Non-canonical mode
+ /// is useful for late optimization passes.
+ void disableCanonicalMode() { CanonicalMode = false; }
+
private:
LLVMContext &getContext() const { return SE.getContext(); }
@@ -121,6 +174,16 @@ namespace llvm {
Value *visitUnknown(const SCEVUnknown *S) {
return S->getValue();
}
+
+ void rememberInstruction(Value *I) {
+ if (!PostIncLoop) InsertedValues.insert(I);
+ }
+
+ Value *expandAddRecExprLiterally(const SCEVAddRecExpr *);
+ PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
+ const Loop *L,
+ const Type *ExpandTy,
+ const Type *IntTy);
};
}
diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h
index 2c50350..64b8b0b 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpressions.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -295,6 +295,13 @@ namespace llvm {
public:
virtual const char *getOperationStr() const { return " + "; }
+ virtual const Type *getType() const {
+ // Use the type of the last operand, which is likely to be a pointer
+ // type, if there is one. This doesn't usually matter, but it can help
+ // reduce casts when the expressions are expanded.
+ return getOperand(getNumOperands() - 1)->getType();
+ }
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEVAddExpr *S) { return true; }
static inline bool classof(const SCEV *S) {
diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h
index 068f81f..7fa5d4a 100644
--- a/include/llvm/Attributes.h
+++ b/include/llvm/Attributes.h
@@ -58,8 +58,6 @@ const Attributes NoRedZone = 1<<22; /// disable redzone
const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point
/// instructions.
const Attributes Naked = 1<<24; ///< Naked function
-const Attributes InlineHint = 1<<25; ///< source said inlining was
- ///desirable
/// @brief Attributes that only apply to function parameters.
const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
@@ -68,7 +66,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
/// be used on return values or function parameters.
const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |
NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq |
- NoRedZone | NoImplicitFloat | Naked | InlineHint;
+ NoRedZone | NoImplicitFloat | Naked;
/// @brief Parameter attributes that do not apply to vararg call arguments.
const Attributes VarArgsIncompatible = StructRet;
diff --git a/include/llvm/CallGraphSCCPass.h b/include/llvm/CallGraphSCCPass.h
index fc9feda..feab763 100644
--- a/include/llvm/CallGraphSCCPass.h
+++ b/include/llvm/CallGraphSCCPass.h
@@ -32,8 +32,8 @@ class PMStack;
struct CallGraphSCCPass : public Pass {
- explicit CallGraphSCCPass(intptr_t pid) : Pass(pid) {}
- explicit CallGraphSCCPass(void *pid) : Pass(pid) {}
+ explicit CallGraphSCCPass(intptr_t pid) : Pass(PT_CallGraphSCC, pid) {}
+ explicit CallGraphSCCPass(void *pid) : Pass(PT_CallGraphSCC, pid) {}
/// doInitialization - This method is called before the SCC's of the program
/// has been processed, allowing the pass to do initialization as necessary.
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 9a07e31..377096c 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -48,10 +48,12 @@ namespace llvm {
class MCSection;
class MCStreamer;
class MCSymbol;
+ class MDNode;
class DwarfWriter;
class Mangler;
class MCAsmInfo;
class TargetLoweringObjectFile;
+ class Twine;
class Type;
class formatted_raw_ostream;
@@ -131,10 +133,10 @@ namespace llvm {
///
Mangler *Mang;
- /// Cache of mangled name for current function. This is recalculated at the
+ /// The symbol for the current function. This is recalculated at the
/// beginning of each call to runOnMachineFunction().
///
- std::string CurrentFnName;
+ MCSymbol *CurrentFnSym;
/// getCurrentSection() - Return the current section we are emitting to.
const MCSection *getCurrentSection() const;
@@ -151,7 +153,7 @@ namespace llvm {
mutable unsigned Counter;
// Private state for processDebugLoc()
- mutable DebugLocTuple PrevDLT;
+ mutable const MDNode *PrevDLT;
protected:
explicit AsmPrinter(formatted_raw_ostream &o, TargetMachine &TM,
@@ -213,10 +215,6 @@ namespace llvm {
unsigned AsmVariant,
const char *ExtraCode);
- /// PrintGlobalVariable - Emit the specified global variable and its
- /// initializer to the output stream.
- virtual void PrintGlobalVariable(const GlobalVariable *GV) = 0;
-
/// SetupMachineFunction - This should be called when a new MachineFunction
/// is being processed from runOnMachineFunction.
void SetupMachineFunction(MachineFunction &MF);
@@ -238,6 +236,9 @@ namespace llvm {
///
void EmitJumpTableInfo(MachineJumpTableInfo *MJTI, MachineFunction &MF);
+ /// EmitGlobalVariable - Emit the specified global variable to the .s file.
+ virtual void EmitGlobalVariable(const GlobalVariable *GV);
+
/// EmitSpecialLLVMGlobal - Check to see if the specified global is a
/// special global used by LLVM. If so, emit it and return true, otherwise
/// do nothing and return false.
@@ -245,39 +246,9 @@ namespace llvm {
public:
//===------------------------------------------------------------------===//
- /// LEB 128 number encoding.
-
- /// PrintULEB128 - Print a series of hexidecimal values(separated by commas)
- /// representing an unsigned leb128 value.
- void PrintULEB128(unsigned Value) const;
-
- /// PrintSLEB128 - Print a series of hexidecimal values(separated by commas)
- /// representing a signed leb128 value.
- void PrintSLEB128(int Value) const;
-
- //===------------------------------------------------------------------===//
// Emission and print routines
//
- /// PrintHex - Print a value as a hexidecimal value.
- ///
- void PrintHex(int Value) const;
-
- /// EOL - Print a newline character to asm stream. If a comment is present
- /// then it will be printed first. Comments should not contain '\n'.
- void EOL() const;
- void EOL(const std::string &Comment) const;
- void EOL(const char* Comment) const;
- void EOL(const char *Comment, unsigned Encoding) const;
-
- /// EmitULEB128Bytes - Emit an assembler byte data directive to compose an
- /// unsigned leb128 value.
- void EmitULEB128Bytes(unsigned Value) const;
-
- /// EmitSLEB128Bytes - print an assembler byte data directive to compose a
- /// signed leb128 value.
- void EmitSLEB128Bytes(int Value) const;
-
/// EmitInt8 - Emit a byte directive and value.
///
void EmitInt8(int Value) const;
@@ -294,14 +265,8 @@ namespace llvm {
///
void EmitInt64(uint64_t Value) const;
- /// EmitString - Emit a string with quotes and a null terminator.
- /// Special characters are emitted properly.
- /// @verbatim (Eg. '\t') @endverbatim
- void EmitString(const StringRef String) const;
- void EmitString(const char *String, unsigned Size) const;
-
/// EmitFile - Emit a .file directive.
- void EmitFile(unsigned Number, const std::string &Name) const;
+ void EmitFile(unsigned Number, StringRef Name) const;
//===------------------------------------------------------------------===//
@@ -336,13 +301,32 @@ namespace llvm {
/// EmitComments - Pretty-print comments for instructions
void EmitComments(const MachineInstr &MI) const;
- /// EmitComments - Pretty-print comments for basic blocks
- void EmitComments(const MachineBasicBlock &MBB) const;
+ /// GetGlobalValueSymbol - Return the MCSymbol for the specified global
+ /// value.
+ MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const;
+
+ /// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with
+ /// global value name as its base, with the specified suffix, and where the
+ /// symbol is forced to have private linkage if ForcePrivate is true.
+ MCSymbol *GetSymbolWithGlobalValueBase(const GlobalValue *GV,
+ StringRef Suffix,
+ bool ForcePrivate = true) const;
+
+ /// GetExternalSymbolSymbol - Return the MCSymbol for the specified
+ /// ExternalSymbol.
+ MCSymbol *GetExternalSymbolSymbol(StringRef Sym) const;
+
/// GetMBBSymbol - Return the MCSymbol corresponding to the specified basic
/// block label.
MCSymbol *GetMBBSymbol(unsigned MBBID) const;
+ /// GetCPISymbol - Return the symbol for the specified constant pool entry.
+ MCSymbol *GetCPISymbol(unsigned CPID) const;
+
+ /// GetJTISymbol - Return the symbol for the specified jump table entry.
+ MCSymbol *GetJTISymbol(unsigned JTID, bool isLinkerPrivate = false) const;
+
/// GetBlockAddressSymbol - Return the MCSymbol used to satisfy BlockAddress
/// uses of the specified basic block.
MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA,
@@ -355,22 +339,14 @@ namespace llvm {
/// MachineBasicBlock, an alignment (if present) and a comment describing
/// it if appropriate.
void EmitBasicBlockStart(const MachineBasicBlock *MBB) const;
- protected:
- /// EmitZeros - Emit a block of zeros.
- ///
- void EmitZeros(uint64_t NumZeros, unsigned AddrSpace = 0) const;
-
- /// EmitString - Emit a zero-byte-terminated string constant.
- ///
- virtual void EmitString(const ConstantArray *CVA) const;
-
- /// EmitConstantValueOnly - Print out the specified constant, without a
- /// storage class. Only constants of first-class type are allowed here.
- void EmitConstantValueOnly(const Constant *CV);
-
+
+
+ // Data emission.
+
/// EmitGlobalConstant - Print a general LLVM constant to the .s file.
void EmitGlobalConstant(const Constant* CV, unsigned AddrSpace = 0);
-
+
+ protected:
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
/// processDebugLoc - Processes the debug information of each machine
@@ -398,26 +374,16 @@ namespace llvm {
const MachineBasicBlock *MBB,
unsigned uid) const;
- /// printDataDirective - This method prints the asm directive for the
- /// specified type.
- void printDataDirective(const Type *type, unsigned AddrSpace = 0);
-
/// printVisibility - This prints visibility information about symbol, if
/// this is suported by the target.
- void printVisibility(const std::string& Name, unsigned Visibility) const;
-
+ void printVisibility(MCSymbol *Sym, unsigned Visibility) const;
+
/// printOffset - This is just convenient handler for printing offsets.
void printOffset(int64_t Offset) const;
private:
void EmitLLVMUsedList(Constant *List);
void EmitXXStructorList(Constant *List);
- void EmitGlobalConstantStruct(const ConstantStruct* CVS,
- unsigned AddrSpace);
- void EmitGlobalConstantArray(const ConstantArray* CVA, unsigned AddrSpace);
- void EmitGlobalConstantVector(const ConstantVector* CP);
- void EmitGlobalConstantFP(const ConstantFP* CFP, unsigned AddrSpace);
- void EmitGlobalConstantLargeInt(const ConstantInt* CI, unsigned AddrSpace);
GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C);
};
}
diff --git a/include/llvm/CodeGen/FileWriters.h b/include/llvm/CodeGen/FileWriters.h
index a913d21..9dba838 100644
--- a/include/llvm/CodeGen/FileWriters.h
+++ b/include/llvm/CodeGen/FileWriters.h
@@ -20,11 +20,17 @@ namespace llvm {
class ObjectCodeEmitter;
class TargetMachine;
class raw_ostream;
+ class formatted_raw_ostream;
+ class MachineFunctionPass;
+ class MCAsmInfo;
+ class MCCodeEmitter;
ObjectCodeEmitter *AddELFWriter(PassManagerBase &FPM, raw_ostream &O,
TargetMachine &TM);
- ObjectCodeEmitter *AddMachOWriter(PassManagerBase &FPM, raw_ostream &O,
- TargetMachine &TM);
+ MachineFunctionPass *createMachOWriter(formatted_raw_ostream &O,
+ TargetMachine &TM,
+ const MCAsmInfo *T,
+ MCCodeEmitter *MCE);
} // end llvm namespace
diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h
index 5608c99..27947e8 100644
--- a/include/llvm/CodeGen/LinkAllCodegenComponents.h
+++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h
@@ -44,6 +44,7 @@ namespace {
(void) llvm::createBURRListDAGScheduler(NULL, llvm::CodeGenOpt::Default);
(void) llvm::createTDRRListDAGScheduler(NULL, llvm::CodeGenOpt::Default);
+ (void) llvm::createSourceListDAGScheduler(NULL,llvm::CodeGenOpt::Default);
(void) llvm::createTDListDAGScheduler(NULL, llvm::CodeGenOpt::Default);
(void) llvm::createFastDAGScheduler(NULL, llvm::CodeGenOpt::Default);
(void) llvm::createDefaultScheduler(NULL, llvm::CodeGenOpt::Default);
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
index 6b4c640..20644c1 100644
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -337,6 +337,10 @@ public:
MachineBasicBlock *DestB,
bool isCond);
+ /// findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping
+ /// any DEBUG_VALUE instructions. Return UnknownLoc if there is none.
+ DebugLoc findDebugLoc(MachineBasicBlock::iterator &MBBI);
+
// Debugging methods.
void dump() const;
void print(raw_ostream &OS) const;
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
index a12a55a..6ca51bf 100644
--- a/include/llvm/CodeGen/MachineFunction.h
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -26,6 +26,7 @@
namespace llvm {
+class DILocation;
class Value;
class Function;
class MachineRegisterInfo;
@@ -174,9 +175,6 @@ public:
AlignOf<Ty>::Alignment));
MFInfo = new (Loc) Ty(*this);
}
-
- assert((void*)dynamic_cast<Ty*>(MFInfo) == (void*)MFInfo &&
- "Invalid concrete type or multiple inheritence for getInfo");
return static_cast<Ty*>(MFInfo);
}
@@ -368,8 +366,8 @@ public:
// Debug location.
//
- /// getDebugLocTuple - Get the DebugLocTuple for a given DebugLoc object.
- DebugLocTuple getDebugLocTuple(DebugLoc DL) const;
+ /// getDILocation - Get the DILocation for a given DebugLoc object.
+ DILocation getDILocation(DebugLoc DL) const;
/// getDefaultDebugLoc - Get the default debug location for the machine
/// function.
diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h
index e9b645b..d365029 100644
--- a/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/include/llvm/CodeGen/MachineModuleInfo.h
@@ -172,9 +172,6 @@ public:
Ty &getObjFileInfo() {
if (ObjFileMMI == 0)
ObjFileMMI = new Ty(*this);
-
- assert((void*)dynamic_cast<Ty*>(ObjFileMMI) == (void*)ObjFileMMI &&
- "Invalid concrete type or multiple inheritence for getInfo");
return *static_cast<Ty*>(ObjFileMMI);
}
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h
index 907c25a..07d886d 100644
--- a/include/llvm/CodeGen/MachineOperand.h
+++ b/include/llvm/CodeGen/MachineOperand.h
@@ -453,11 +453,9 @@ public:
Op.setTargetFlags(TargetFlags);
return Op;
}
- static MachineOperand CreateMetadata(MDNode *Meta,
- unsigned char TargetFlags = 0) {
+ static MachineOperand CreateMetadata(MDNode *Meta) {
MachineOperand Op(MachineOperand::MO_Metadata);
Op.Contents.MD = Meta;
- Op.setTargetFlags(TargetFlags);
return Op;
}
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 2203f8c..7e0da3f 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -195,10 +195,6 @@ namespace llvm {
/// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow.
FunctionPass *createSjLjEHPass(const TargetLowering *tli);
- /// createMaxStackAlignmentCalculatorPass() - Determine the maximum required
- /// alignment for a function.
- FunctionPass* createMaxStackAlignmentCalculatorPass();
-
} // End llvm namespace
#endif
diff --git a/include/llvm/CodeGen/SchedulerRegistry.h b/include/llvm/CodeGen/SchedulerRegistry.h
index 1cf64a0..cf3274f 100644
--- a/include/llvm/CodeGen/SchedulerRegistry.h
+++ b/include/llvm/CodeGen/SchedulerRegistry.h
@@ -73,6 +73,11 @@ ScheduleDAGSDNodes *createBURRListDAGScheduler(SelectionDAGISel *IS,
ScheduleDAGSDNodes *createTDRRListDAGScheduler(SelectionDAGISel *IS,
CodeGenOpt::Level OptLevel);
+/// createBURRListDAGScheduler - This creates a bottom up register usage
+/// reduction list scheduler that schedules in source code order when possible.
+ScheduleDAGSDNodes *createSourceListDAGScheduler(SelectionDAGISel *IS,
+ CodeGenOpt::Level OptLevel);
+
/// createTDListDAGScheduler - This creates a top-down list scheduler with
/// a hazard recognizer.
ScheduleDAGSDNodes *createTDListDAGScheduler(SelectionDAGISel *IS,
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index d55dd7f..33ebd00 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -63,6 +63,10 @@ enum CombineLevel {
NoIllegalOperations // Combine may only create legal operations and types.
};
+class SelectionDAG;
+void checkForCycles(const SDNode *N);
+void checkForCycles(const SelectionDAG *DAG);
+
/// SelectionDAG class - This is used to represent a portion of an LLVM function
/// in a low-level Data Dependence DAG representation suitable for instruction
/// selection. This DAG is constructed as the first step of instruction
@@ -204,7 +208,12 @@ public:
const SDValue &setRoot(SDValue N) {
assert((!N.getNode() || N.getValueType() == MVT::Other) &&
"DAG root value is not a chain!");
- return Root = N;
+ if (N.getNode())
+ checkForCycles(N.getNode());
+ Root = N;
+ if (N.getNode())
+ checkForCycles(this);
+ return Root;
}
/// Combine - This iterates over the nodes in the SelectionDAG, folding
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 7b1931a..45a9d40 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -44,6 +44,8 @@ template <typename T> struct DenseMapInfo;
template <typename T> struct simplify_type;
template <typename T> struct ilist_traits;
+void checkForCycles(const SDNode *N);
+
/// SDVTList - This represents a list of ValueType's that has been intern'd by
/// a SelectionDAG. Instances of this simple value class are returned by
/// SelectionDAG::getVTList(...).
@@ -1285,11 +1287,56 @@ public:
void print_details(raw_ostream &OS, const SelectionDAG *G) const;
void print(raw_ostream &OS, const SelectionDAG *G = 0) const;
void printr(raw_ostream &OS, const SelectionDAG *G = 0) const;
+
+ /// printrFull - Print a SelectionDAG node and all children down to
+ /// the leaves. The given SelectionDAG allows target-specific nodes
+ /// to be printed in human-readable form. Unlike printr, this will
+ /// print the whole DAG, including children that appear multiple
+ /// times.
+ ///
+ void printrFull(raw_ostream &O, const SelectionDAG *G = 0) const;
+
+ /// printrWithDepth - Print a SelectionDAG node and children up to
+ /// depth "depth." The given SelectionDAG allows target-specific
+ /// nodes to be printed in human-readable form. Unlike printr, this
+ /// will print children that appear multiple times wherever they are
+ /// used.
+ ///
+ void printrWithDepth(raw_ostream &O, const SelectionDAG *G = 0,
+ unsigned depth = 100) const;
+
+
+ /// dump - Dump this node, for debugging.
void dump() const;
+
+ /// dumpr - Dump (recursively) this node and its use-def subgraph.
void dumpr() const;
+
+ /// dump - Dump this node, for debugging.
+ /// The given SelectionDAG allows target-specific nodes to be printed
+ /// in human-readable form.
void dump(const SelectionDAG *G) const;
+
+ /// dumpr - Dump (recursively) this node and its use-def subgraph.
+ /// The given SelectionDAG allows target-specific nodes to be printed
+ /// in human-readable form.
void dumpr(const SelectionDAG *G) const;
+ /// dumprFull - printrFull to dbgs(). The given SelectionDAG allows
+ /// target-specific nodes to be printed in human-readable form.
+ /// Unlike dumpr, this will print the whole DAG, including children
+ /// that appear multiple times.
+ ///
+ void dumprFull(const SelectionDAG *G = 0) const;
+
+ /// dumprWithDepth - printrWithDepth to dbgs(). The given
+ /// SelectionDAG allows target-specific nodes to be printed in
+ /// human-readable form. Unlike dumpr, this will print children
+ /// that appear multiple times wherever they are used.
+ ///
+ void dumprWithDepth(const SelectionDAG *G = 0, unsigned depth = 100) const;
+
+
static bool classof(const SDNode *) { return true; }
/// Profile - Gather unique data for the node.
@@ -1318,6 +1365,7 @@ protected:
OperandList[i].setUser(this);
OperandList[i].setInitial(Ops[i]);
}
+ checkForCycles(this);
}
/// This constructor adds no operands itself; operands can be
@@ -1334,6 +1382,7 @@ protected:
Ops[0].setInitial(Op0);
NumOperands = 1;
OperandList = Ops;
+ checkForCycles(this);
}
/// InitOperands - Initialize the operands list of this with 2 operands.
@@ -1344,6 +1393,7 @@ protected:
Ops[1].setInitial(Op1);
NumOperands = 2;
OperandList = Ops;
+ checkForCycles(this);
}
/// InitOperands - Initialize the operands list of this with 3 operands.
@@ -1357,6 +1407,7 @@ protected:
Ops[2].setInitial(Op2);
NumOperands = 3;
OperandList = Ops;
+ checkForCycles(this);
}
/// InitOperands - Initialize the operands list of this with 4 operands.
@@ -1372,6 +1423,7 @@ protected:
Ops[3].setInitial(Op3);
NumOperands = 4;
OperandList = Ops;
+ checkForCycles(this);
}
/// InitOperands - Initialize the operands list of this with N operands.
@@ -1382,6 +1434,7 @@ protected:
}
NumOperands = N;
OperandList = Ops;
+ checkForCycles(this);
}
/// DropOperands - Release the operands and set this node to have
diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h
index 85aaa7f..b5cc659 100644
--- a/include/llvm/InstrTypes.h
+++ b/include/llvm/InstrTypes.h
@@ -652,8 +652,7 @@ public:
/// This class is the base class for the comparison instructions.
/// @brief Abstract base class of comparison instructions.
-// FIXME: why not derive from BinaryOperator?
-class CmpInst: public Instruction {
+class CmpInst : public Instruction {
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
CmpInst(); // do not implement
protected:
@@ -665,6 +664,7 @@ protected:
Value *LHS, Value *RHS, const Twine &Name,
BasicBlock *InsertAtEnd);
+ virtual void Anchor() const; // Out of line virtual method.
public:
/// This enumeration lists the possible predicates for CmpInst subclasses.
/// Values in the range 0-31 are reserved for FCmpInst, while values in the
diff --git a/include/llvm/IntrinsicInst.h b/include/llvm/IntrinsicInst.h
index f40e8cc..d86b33e 100644
--- a/include/llvm/IntrinsicInst.h
+++ b/include/llvm/IntrinsicInst.h
@@ -25,7 +25,6 @@
#define LLVM_INTRINSICINST_H
#include "llvm/Constants.h"
-#include "llvm/Metadata.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
@@ -83,12 +82,7 @@ namespace llvm {
///
class DbgDeclareInst : public DbgInfoIntrinsic {
public:
- Value *getAddress() const {
- if (MDNode* MD = dyn_cast<MDNode>(getOperand(1)))
- return MD->getOperand(0);
- else
- return NULL;
- }
+ Value *getAddress() const;
MDNode *getVariable() const { return cast<MDNode>(getOperand(2)); }
// Methods for support type inquiry through isa, cast, and dyn_cast:
diff --git a/include/llvm/LinkAllVMCore.h b/include/llvm/LinkAllVMCore.h
index 2145bf8..6cf2c4b 100644
--- a/include/llvm/LinkAllVMCore.h
+++ b/include/llvm/LinkAllVMCore.h
@@ -32,7 +32,6 @@
#include "llvm/System/Signals.h"
#include "llvm/System/TimeValue.h"
#include "llvm/Support/Dwarf.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/SlowOperationInformer.h"
#include <cstdlib>
@@ -46,10 +45,9 @@ namespace {
// to know that getenv() never returns -1, this will do the job.
if (std::getenv("bar") != (char*) -1)
return;
- llvm::Module* M = new llvm::Module("", llvm::getGlobalContext());
+ (void)new llvm::Module("", llvm::getGlobalContext());
(void)new llvm::UnreachableInst(llvm::getGlobalContext());
(void) llvm::createVerifierPass();
- (void) new llvm::Mangler(*M,"");
}
} ForceVMCoreLinking;
}
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index fb69630..5e31dfe 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -16,9 +16,13 @@
#ifndef LLVM_TARGET_ASM_INFO_H
#define LLVM_TARGET_ASM_INFO_H
+#include "llvm/MC/MCDirectives.h"
#include <cassert>
namespace llvm {
+ class MCSection;
+ class MCContext;
+
/// MCAsmInfo - This class is intended to be used as a base class for asm
/// properties and features specific to the target.
namespace ExceptionHandling { enum ExceptionsType { None, Dwarf, SjLj }; }
@@ -29,15 +33,20 @@ namespace llvm {
// Properties to be set by the target writer, used to configure asm printer.
//
- /// ZeroFillDirective - Directive for emitting a global to the ZeroFill
- /// section on this target. Null if this target doesn't support zerofill.
- const char *ZeroFillDirective; // Default is null.
-
- /// NonexecutableStackDirective - Directive for declaring to the
- /// linker and beyond that the emitted code does not require stack
- /// memory to be executable.
- const char *NonexecutableStackDirective; // Default is null.
-
+ /// HasSubsectionsViaSymbols - True if this target has the MachO
+ /// .subsections_via_symbols directive.
+ bool HasSubsectionsViaSymbols; // Default is false.
+
+ /// HasMachoZeroFillDirective - True if this is a MachO target that supports
+ /// the macho-specific .zerofill directive for emitting BSS Symbols.
+ bool HasMachoZeroFillDirective; // Default is false.
+
+ /// HasStaticCtorDtorReferenceInStaticMode - True if the compiler should
+ /// emit a ".reference .constructors_used" or ".reference .destructors_used"
+ /// directive after the a static ctor/dtor list. This directive is only
+ /// emitted in Static relocation model.
+ bool HasStaticCtorDtorReferenceInStaticMode; // Default is false.
+
/// NeedsSet - True if target asm treats expressions in data directives
/// as linktime-relocatable. For assembly-time computation, we need to
/// use a .set. Thus:
@@ -107,7 +116,6 @@ namespace llvm {
/// "\t.zero\t" and "\t.space\t". If this is set to null, the
/// Data*bitsDirective's will be used to emit zero bytes.
const char *ZeroDirective; // Defaults to "\t.zero\t"
- const char *ZeroDirectiveSuffix; // Defaults to ""
/// AsciiDirective - This directive allows emission of an ascii string with
/// the standard C escape characters embedded into it.
@@ -183,15 +191,10 @@ namespace llvm {
/// the assembler to set the value of a variable to some expression.
const char *SetDirective; // Defaults to null.
- /// LCOMMDirective - This is the name of a directive (if supported) that can
- /// be used to efficiently declare a local (internal) block of zero
- /// initialized data in the .bss/.data section. The syntax expected is:
- /// @verbatim <LCOMMDirective> SYMBOLNAME LENGTHINBYTES, ALIGNMENT
- /// @endverbatim
- const char *LCOMMDirective; // Defaults to null.
+ /// HasLCOMMDirective - This is true if the target supports the .lcomm
+ /// directive.
+ bool HasLCOMMDirective; // Defaults to false.
- const char *COMMDirective; // Defaults to "\t.comm\t".
-
/// COMMDirectiveTakesAlignment - True if COMMDirective take a third
/// argument that specifies the alignment of the declaration.
bool COMMDirectiveTakesAlignment; // Defaults to true.
@@ -204,10 +207,9 @@ namespace llvm {
/// .file directive, this is true for ELF targets.
bool HasSingleParameterDotFile; // Defaults to true.
- /// UsedDirective - This directive, if non-null, is used to declare a global
- /// as being used somehow that the assembler can't see. This prevents dead
- /// code elimination on some targets.
- const char *UsedDirective; // Defaults to NULL.
+ /// HasNoDeadStrip - True if this target supports the MachO .no_dead_strip
+ /// directive.
+ bool HasNoDeadStrip; // Defaults to false.
/// WeakRefDirective - This directive, if non-null, is used to declare a
/// global as being a weak undefined symbol.
@@ -216,14 +218,18 @@ namespace llvm {
/// WeakDefDirective - This directive, if non-null, is used to declare a
/// global as being a weak defined symbol.
const char *WeakDefDirective; // Defaults to NULL.
+
+ /// LinkOnceDirective - This directive, if non-null is used to declare a
+ /// global as being a weak defined symbol. This is used on cygwin/mingw.
+ const char *LinkOnceDirective; // Defaults to NULL.
- /// HiddenDirective - This directive, if non-null, is used to declare a
- /// global or function as having hidden visibility.
- const char *HiddenDirective; // Defaults to "\t.hidden\t".
+ /// HiddenVisibilityAttr - This attribute, if not MCSA_Invalid, is used to
+ /// declare a symbol as having hidden visibility.
+ MCSymbolAttr HiddenVisibilityAttr; // Defaults to MCSA_Hidden.
- /// ProtectedDirective - This directive, if non-null, is used to declare a
- /// global or function as having protected visibility.
- const char *ProtectedDirective; // Defaults to "\t.protected\t".
+ /// ProtectedVisibilityAttr - This attribute, if not MCSA_Invalid, is used
+ /// to declare a symbol as having protected visibility.
+ MCSymbolAttr ProtectedVisibilityAttr; // Defaults to MCSA_Protected
//===--- Dwarf Emission Directives -----------------------------------===//
@@ -279,14 +285,12 @@ namespace llvm {
explicit MCAsmInfo();
virtual ~MCAsmInfo();
- /// getSLEB128Size - Compute the number of bytes required for a signed
- /// leb128 value.
+ // FIXME: move these methods to DwarfPrinter when the JIT stops using them.
static unsigned getSLEB128Size(int Value);
-
- /// getULEB128Size - Compute the number of bytes required for an unsigned
- /// leb128 value.
static unsigned getULEB128Size(unsigned Value);
+ bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; }
+
// Data directive accessors.
//
const char *getData8bitsDirective(unsigned AS = 0) const {
@@ -302,6 +306,12 @@ namespace llvm {
return AS == 0 ? Data64bitsDirective : getDataASDirective(64, AS);
}
+ /// getNonexecutableStackSection - Targets can implement this method to
+ /// specify a section to switch to if the translation unit doesn't have any
+ /// trampolines that require an executable stack.
+ virtual MCSection *getNonexecutableStackSection(MCContext &Ctx) const {
+ return 0;
+ }
bool usesSunStyleELFSectionSwitchSyntax() const {
return SunStyleELFSectionSwitchSyntax;
@@ -313,11 +323,9 @@ namespace llvm {
// Accessors.
//
- const char *getZeroFillDirective() const {
- return ZeroFillDirective;
- }
- const char *getNonexecutableStackDirective() const {
- return NonexecutableStackDirective;
+ bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; }
+ bool hasStaticCtorDtorReferenceInStaticMode() const {
+ return HasStaticCtorDtorReferenceInStaticMode;
}
bool needsSet() const {
return NeedsSet;
@@ -364,9 +372,6 @@ namespace llvm {
const char *getZeroDirective() const {
return ZeroDirective;
}
- const char *getZeroDirectiveSuffix() const {
- return ZeroDirectiveSuffix;
- }
const char *getAsciiDirective() const {
return AsciiDirective;
}
@@ -394,35 +399,20 @@ namespace llvm {
const char *getSetDirective() const {
return SetDirective;
}
- const char *getLCOMMDirective() const {
- return LCOMMDirective;
- }
- const char *getCOMMDirective() const {
- return COMMDirective;
- }
+ bool hasLCOMMDirective() const { return HasLCOMMDirective; }
bool getCOMMDirectiveTakesAlignment() const {
return COMMDirectiveTakesAlignment;
}
- bool hasDotTypeDotSizeDirective() const {
- return HasDotTypeDotSizeDirective;
- }
- bool hasSingleParameterDotFile() const {
- return HasSingleParameterDotFile;
- }
- const char *getUsedDirective() const {
- return UsedDirective;
- }
- const char *getWeakRefDirective() const {
- return WeakRefDirective;
- }
- const char *getWeakDefDirective() const {
- return WeakDefDirective;
- }
- const char *getHiddenDirective() const {
- return HiddenDirective;
- }
- const char *getProtectedDirective() const {
- return ProtectedDirective;
+ bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;}
+ bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; }
+ bool hasNoDeadStrip() const { return HasNoDeadStrip; }
+ const char *getWeakRefDirective() const { return WeakRefDirective; }
+ const char *getWeakDefDirective() const { return WeakDefDirective; }
+ const char *getLinkOnceDirective() const { return LinkOnceDirective; }
+
+ MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr;}
+ MCSymbolAttr getProtectedVisibilityAttr() const {
+ return ProtectedVisibilityAttr;
}
bool isAbsoluteDebugSectionOffsets() const {
return AbsoluteDebugSectionOffsets;
diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h
new file mode 100644
index 0000000..57ce75d
--- /dev/null
+++ b/include/llvm/MC/MCDirectives.h
@@ -0,0 +1,44 @@
+//===- MCDirectives.h - Enums for directives on various targets -*- 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 various enums that represent target-specific directives.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCDIRECTIVES_H
+#define LLVM_MC_MCDIRECTIVES_H
+
+namespace llvm {
+
+enum MCSymbolAttr {
+ MCSA_Invalid = 0, /// Not a valid directive.
+
+ // Various directives in alphabetical order.
+ MCSA_Global, /// .globl
+ MCSA_Hidden, /// .hidden (ELF)
+ MCSA_IndirectSymbol, /// .indirect_symbol (MachO)
+ MCSA_Internal, /// .internal (ELF)
+ MCSA_LazyReference, /// .lazy_reference (MachO)
+ MCSA_Local, /// .local (ELF)
+ MCSA_NoDeadStrip, /// .no_dead_strip (MachO)
+ MCSA_PrivateExtern, /// .private_extern (MachO)
+ MCSA_Protected, /// .protected (ELF)
+ MCSA_Reference, /// .reference (MachO)
+ MCSA_Weak, /// .weak
+ MCSA_WeakDefinition, /// .weak_definition (MachO)
+ MCSA_WeakReference /// .weak_reference (MachO)
+};
+
+enum MCAssemblerFlag {
+ MCAF_SubsectionsViaSymbols /// .subsections_via_symbols (MachO)
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
index 13d40ec..73d5f8e 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -51,7 +51,7 @@ public:
/// @name Utility Methods
/// @{
- void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
+ void print(raw_ostream &OS) const;
void dump() const;
/// @}
@@ -75,6 +75,11 @@ public:
static bool classof(const MCExpr *) { return true; }
};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
+ E.print(OS);
+ return OS;
+}
//// MCConstantExpr - Represent a constant integer expression.
class MCConstantExpr : public MCExpr {
diff --git a/include/llvm/MC/MCParser/AsmCond.h b/include/llvm/MC/MCParser/AsmCond.h
new file mode 100644
index 0000000..92a115e
--- /dev/null
+++ b/include/llvm/MC/MCParser/AsmCond.h
@@ -0,0 +1,40 @@
+//===- AsmCond.h - Assembly file conditional assembly ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ASMCOND_H
+#define ASMCOND_H
+
+namespace llvm {
+
+/// AsmCond - Class to support conditional assembly
+///
+/// The conditional assembly feature (.if, .else, .elseif and .endif) is
+/// implemented with AsmCond that tells us what we are in the middle of
+/// processing. Ignore can be either true or false. When true we are ignoring
+/// the block of code in the middle of a conditional.
+
+class AsmCond {
+public:
+ enum ConditionalAssemblyType {
+ NoCond, // no conditional is being processed
+ IfCond, // inside if conditional
+ ElseIfCond, // inside elseif conditional
+ ElseCond // inside else conditional
+ };
+
+ ConditionalAssemblyType TheCond;
+ bool CondMet;
+ bool Ignore;
+
+ AsmCond() : TheCond(NoCond), CondMet(false), Ignore(false) {}
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h
new file mode 100644
index 0000000..cf6eefb
--- /dev/null
+++ b/include/llvm/MC/MCParser/AsmLexer.h
@@ -0,0 +1,72 @@
+//===- AsmLexer.h - Lexer for Assembly Files --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class declares the lexer for assembly files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ASMLEXER_H
+#define ASMLEXER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/System/DataTypes.h"
+#include <string>
+#include <cassert>
+
+namespace llvm {
+class MemoryBuffer;
+class SMLoc;
+class MCAsmInfo;
+
+/// AsmLexer - Lexer class for assembly files.
+class AsmLexer : public MCAsmLexer {
+ const MCAsmInfo &MAI;
+
+ const char *CurPtr;
+ const MemoryBuffer *CurBuf;
+
+ const char *TokStart;
+
+ void operator=(const AsmLexer&); // DO NOT IMPLEMENT
+ AsmLexer(const AsmLexer&); // DO NOT IMPLEMENT
+
+protected:
+ /// LexToken - Read the next token and return its code.
+ virtual AsmToken LexToken();
+
+public:
+ AsmLexer(const MCAsmInfo &MAI);
+ ~AsmLexer();
+
+ void setBuffer(const MemoryBuffer *buf, const char *ptr = NULL);
+
+ SMLoc getLoc() const;
+
+ StringRef LexUntilEndOfStatement();
+
+ bool isAtStartOfComment(char Char);
+
+ const MCAsmInfo &getMAI() const { return MAI; }
+
+private:
+ int getNextChar();
+ AsmToken ReturnError(const char *Loc, const std::string &Msg);
+
+ AsmToken LexIdentifier();
+ AsmToken LexSlash();
+ AsmToken LexLineComment();
+ AsmToken LexDigit();
+ AsmToken LexQuote();
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCParser/AsmParser.h b/include/llvm/MC/MCParser/AsmParser.h
new file mode 100644
index 0000000..f82584c
--- /dev/null
+++ b/include/llvm/MC/MCParser/AsmParser.h
@@ -0,0 +1,178 @@
+//===- AsmParser.h - Parser for Assembly Files ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class declares the parser for assembly files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ASMPARSER_H
+#define ASMPARSER_H
+
+#include <vector>
+#include "llvm/MC/MCParser/AsmLexer.h"
+#include "llvm/MC/MCParser/AsmCond.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/ADT/StringMap.h"
+
+namespace llvm {
+class AsmCond;
+class AsmToken;
+class MCContext;
+class MCExpr;
+class MCInst;
+class MCStreamer;
+class MCAsmInfo;
+class MCValue;
+class SourceMgr;
+class TargetAsmParser;
+class Twine;
+
+class AsmParser : public MCAsmParser {
+private:
+ AsmLexer Lexer;
+ MCContext &Ctx;
+ MCStreamer &Out;
+ SourceMgr &SrcMgr;
+ TargetAsmParser *TargetParser;
+
+ /// This is the current buffer index we're lexing from as managed by the
+ /// SourceMgr object.
+ int CurBuffer;
+
+ AsmCond TheCondState;
+ std::vector<AsmCond> TheCondStack;
+
+ // FIXME: Figure out where this should leave, the code is a copy of that which
+ // is also used by TargetLoweringObjectFile.
+ mutable void *SectionUniquingMap;
+
+ /// DirectiveMap - This is a table handlers for directives. Each handler is
+ /// invoked after the directive identifier is read and is responsible for
+ /// parsing and validating the rest of the directive. The handler is passed
+ /// in the directive name and the location of the directive keyword.
+ StringMap<bool(AsmParser::*)(StringRef, SMLoc)> DirectiveMap;
+public:
+ AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out,
+ const MCAsmInfo &_MAI);
+ ~AsmParser();
+
+ bool Run();
+
+
+ void AddDirectiveHandler(StringRef Directive,
+ bool (AsmParser::*Handler)(StringRef, SMLoc)) {
+ DirectiveMap[Directive] = Handler;
+ }
+public:
+ TargetAsmParser &getTargetParser() const { return *TargetParser; }
+ void setTargetParser(TargetAsmParser &P) { TargetParser = &P; }
+
+ /// @name MCAsmParser Interface
+ /// {
+
+ virtual MCAsmLexer &getLexer() { return Lexer; }
+ virtual MCContext &getContext() { return Ctx; }
+ virtual MCStreamer &getStreamer() { return Out; }
+
+ virtual void Warning(SMLoc L, const Twine &Meg);
+ virtual bool Error(SMLoc L, const Twine &Msg);
+
+ const AsmToken &Lex();
+
+ bool ParseExpression(const MCExpr *&Res);
+ virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc);
+ virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc);
+ virtual bool ParseAbsoluteExpression(int64_t &Res);
+
+ /// }
+
+private:
+ MCSymbol *CreateSymbol(StringRef Name);
+
+ // FIXME: See comment on SectionUniquingMap.
+ const MCSection *getMachOSection(const StringRef &Segment,
+ const StringRef &Section,
+ unsigned TypeAndAttributes,
+ unsigned Reserved2,
+ SectionKind Kind) const;
+
+ bool ParseStatement();
+
+ bool TokError(const char *Msg);
+
+ void PrintMessage(SMLoc Loc, const std::string &Msg, const char *Type) const;
+
+ /// EnterIncludeFile - Enter the specified file. This returns true on failure.
+ bool EnterIncludeFile(const std::string &Filename);
+
+ bool ParseConditionalAssemblyDirectives(StringRef Directive,
+ SMLoc DirectiveLoc);
+ void EatToEndOfStatement();
+
+ bool ParseAssignment(const StringRef &Name);
+
+ bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc);
+ bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
+ bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
+
+ /// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
+ /// and set \arg Res to the identifier contents.
+ bool ParseIdentifier(StringRef &Res);
+
+ // Directive Parsing.
+ bool ParseDirectiveDarwinSection(); // Darwin specific ".section".
+ bool ParseDirectiveSectionSwitch(const char *Segment, const char *Section,
+ unsigned TAA = 0, unsigned ImplicitAlign = 0,
+ unsigned StubSize = 0);
+ bool ParseDirectiveAscii(bool ZeroTerminated); // ".ascii", ".asciiz"
+ bool ParseDirectiveValue(unsigned Size); // ".byte", ".long", ...
+ bool ParseDirectiveFill(); // ".fill"
+ bool ParseDirectiveSpace(); // ".space"
+ bool ParseDirectiveSet(); // ".set"
+ bool ParseDirectiveOrg(); // ".org"
+ // ".align{,32}", ".p2align{,w,l}"
+ bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize);
+
+ /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which
+ /// accepts a single symbol (which should be a label or an external).
+ bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr);
+ bool ParseDirectiveDarwinSymbolDesc(); // Darwin specific ".desc"
+ bool ParseDirectiveDarwinLsym(); // Darwin specific ".lsym"
+
+ bool ParseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm"
+ bool ParseDirectiveDarwinZerofill(); // Darwin specific ".zerofill"
+
+ // Darwin specific ".subsections_via_symbols"
+ bool ParseDirectiveDarwinSubsectionsViaSymbols();
+ // Darwin specific .dump and .load
+ bool ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump);
+
+ bool ParseDirectiveAbort(); // ".abort"
+ bool ParseDirectiveInclude(); // ".include"
+
+ bool ParseDirectiveIf(SMLoc DirectiveLoc); // ".if"
+ bool ParseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif"
+ bool ParseDirectiveElse(SMLoc DirectiveLoc); // ".else"
+ bool ParseDirectiveEndIf(SMLoc DirectiveLoc); // .endif
+
+ bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc); // ".file"
+ bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc); // ".line"
+ bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc); // ".loc"
+
+ /// ParseEscapedString - Parse the current token as a string which may include
+ /// escaped characters and return the string contents.
+ bool ParseEscapedString(std::string &Data);
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h
index e9a6e3f..043c363 100644
--- a/include/llvm/MC/MCAsmLexer.h
+++ b/include/llvm/MC/MCParser/MCAsmLexer.h
@@ -12,11 +12,11 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/System/DataTypes.h"
+#include "llvm/Support/SMLoc.h"
namespace llvm {
class MCAsmLexer;
class MCInst;
-class SMLoc;
class Target;
/// AsmToken - Target independent representation for an assembler token.
@@ -33,6 +33,9 @@ public:
// Integer values.
Integer,
+ // Register values (stored in IntVal). Only used by TargetAsmLexer.
+ Register,
+
// No-value.
EndOfStatement,
Colon,
@@ -96,6 +99,13 @@ public:
assert(Kind == Integer && "This token isn't an integer!");
return IntVal;
}
+
+ /// getRegVal - Get the register number for the current token, which should
+ /// be a register.
+ unsigned getRegVal() const {
+ assert(Kind == Register && "This token isn't a register!");
+ return static_cast<unsigned>(IntVal);
+ }
};
/// MCAsmLexer - Generic assembler lexer interface, for use by target specific
@@ -103,6 +113,10 @@ public:
class MCAsmLexer {
/// The current token, stored in the base class for faster access.
AsmToken CurTok;
+
+ /// The location and description of the current error
+ SMLoc ErrLoc;
+ std::string Err;
MCAsmLexer(const MCAsmLexer &); // DO NOT IMPLEMENT
void operator=(const MCAsmLexer &); // DO NOT IMPLEMENT
@@ -110,7 +124,12 @@ protected: // Can only create subclasses.
MCAsmLexer();
virtual AsmToken LexToken() = 0;
-
+
+ void SetError(const SMLoc &errLoc, const std::string &err) {
+ ErrLoc = errLoc;
+ Err = err;
+ }
+
public:
virtual ~MCAsmLexer();
@@ -126,6 +145,16 @@ public:
const AsmToken &getTok() {
return CurTok;
}
+
+ /// getErrLoc - Get the current error location
+ const SMLoc &getErrLoc() {
+ return ErrLoc;
+ }
+
+ /// getErr - Get the current error string
+ const std::string &getErr() {
+ return Err;
+ }
/// getKind - Get the kind of current token.
AsmToken::TokenKind getKind() const { return CurTok.getKind(); }
diff --git a/include/llvm/MC/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h
index d530093..843c692 100644
--- a/include/llvm/MC/MCAsmParser.h
+++ b/include/llvm/MC/MCParser/MCAsmParser.h
@@ -13,6 +13,7 @@
#include "llvm/System/DataTypes.h"
namespace llvm {
+class AsmToken;
class MCAsmLexer;
class MCContext;
class MCExpr;
@@ -50,20 +51,28 @@ public:
/// clients.
virtual bool Error(SMLoc L, const Twine &Msg) = 0;
+ /// Lex - Get the next AsmToken in the stream, possibly handling file
+ /// inclusion first.
+ virtual const AsmToken &Lex() = 0;
+
+ /// getTok - Get the current AsmToken from the stream.
+ const AsmToken &getTok();
+
/// ParseExpression - Parse an arbitrary expression.
///
/// @param Res - The value of the expression. The result is undefined
/// on error.
/// @result - False on success.
- virtual bool ParseExpression(const MCExpr *&Res) = 0;
-
+ virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
+ bool ParseExpression(const MCExpr *&Res);
+
/// ParseParenExpression - Parse an arbitrary expression, assuming that an
/// initial '(' has already been consumed.
///
/// @param Res - The value of the expression. The result is undefined
/// on error.
/// @result - False on success.
- virtual bool ParseParenExpression(const MCExpr *&Res) = 0;
+ virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
/// ParseAbsoluteExpression - Parse an expression which must evaluate to an
/// absolute value.
diff --git a/include/llvm/MC/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
index 7c2f5be..7c2f5be 100644
--- a/include/llvm/MC/MCParsedAsmOperand.h
+++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h
index 4ec745f..2dccf5c 100644
--- a/include/llvm/MC/MCSectionELF.h
+++ b/include/llvm/MC/MCSectionELF.h
@@ -31,7 +31,7 @@ class MCSectionELF : public MCSection {
unsigned Flags;
/// IsExplicit - Indicates that this section comes from globals with an
- /// explicit section specfied.
+ /// explicit section specified.
bool IsExplicit;
protected:
@@ -47,8 +47,7 @@ public:
/// ShouldOmitSectionDirective - Decides whether a '.section' directive
/// should be printed before the section name
- bool ShouldOmitSectionDirective(const char *Name,
- const MCAsmInfo &MAI) const;
+ bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
/// ShouldPrintSectionType - Only prints the section type if supported
bool ShouldPrintSectionType(unsigned Ty) const;
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 5febed7..2bcb594 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -15,6 +15,7 @@
#define LLVM_MC_MCSTREAMER_H
#include "llvm/System/DataTypes.h"
+#include "llvm/MC/MCDirectives.h"
namespace llvm {
class MCAsmInfo;
@@ -26,7 +27,9 @@ namespace llvm {
class MCSection;
class MCSymbol;
class StringRef;
+ class Twine;
class raw_ostream;
+ class formatted_raw_ostream;
/// MCStreamer - Streaming machine code generation interface. This interface
/// is intended to provide a programatic interface that is very similar to the
@@ -38,30 +41,6 @@ namespace llvm {
/// a .s file, and implementations that write out .o files of various formats.
///
class MCStreamer {
- public:
- enum SymbolAttr {
- Global, /// .globl
- Hidden, /// .hidden (ELF)
- IndirectSymbol, /// .indirect_symbol (Apple)
- Internal, /// .internal (ELF)
- LazyReference, /// .lazy_reference (Apple)
- NoDeadStrip, /// .no_dead_strip (Apple)
- PrivateExtern, /// .private_extern (Apple)
- Protected, /// .protected (ELF)
- Reference, /// .reference (Apple)
- Weak, /// .weak
- WeakDefinition, /// .weak_definition (Apple)
- WeakReference, /// .weak_reference (Apple)
-
- SymbolAttrFirst = Global,
- SymbolAttrLast = WeakReference
- };
-
- enum AssemblerFlag {
- SubsectionsViaSymbols /// .subsections_via_symbols (Apple)
- };
-
- private:
MCContext &Context;
MCStreamer(const MCStreamer&); // DO NOT IMPLEMENT
@@ -79,6 +58,28 @@ namespace llvm {
MCContext &getContext() const { return Context; }
+ /// @name Assembly File Formatting.
+ /// @{
+
+ /// AddComment - Add a comment that can be emitted to the generated .s
+ /// file if applicable as a QoI issue to make the output of the compiler
+ /// more readable. This only affects the MCAsmStreamer, and only when
+ /// verbose assembly output is enabled.
+ ///
+ /// If the comment includes embedded \n's, they will each get the comment
+ /// prefix as appropriate. The added comment should not end with a \n.
+ virtual void AddComment(const Twine &T) {}
+
+ /// GetCommentOS - Return a raw_ostream that comments can be written to.
+ /// Unlike AddComment, you are required to terminate comments with \n if you
+ /// use this method.
+ virtual raw_ostream &GetCommentOS();
+
+ /// AddBlankLine - Emit a blank line to a .s file to pretty it up.
+ virtual void AddBlankLine() {}
+
+ /// @}
+
/// @name Symbol & Section Management
/// @{
@@ -103,7 +104,7 @@ namespace llvm {
virtual void EmitLabel(MCSymbol *Symbol) = 0;
/// EmitAssemblerFlag - Note in the output the specified @param Flag
- virtual void EmitAssemblerFlag(AssemblerFlag Flag) = 0;
+ virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0;
/// EmitAssignment - Emit an assignment of @param Value to @param Symbol.
///
@@ -120,7 +121,7 @@ namespace llvm {
/// EmitSymbolAttribute - Add the given @param Attribute to @param Symbol.
virtual void EmitSymbolAttribute(MCSymbol *Symbol,
- SymbolAttr Attribute) = 0;
+ MCSymbolAttr Attribute) = 0;
/// EmitSymbolDesc - Set the @param DescValue for the @param Symbol.
///
@@ -128,15 +129,21 @@ namespace llvm {
/// @param DescValue - The value to set into the n_desc field.
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) = 0;
- /// EmitCommonSymbol - Emit a common or local common symbol.
+ /// EmitCommonSymbol - Emit a common symbol.
///
/// @param Symbol - The common symbol to emit.
/// @param Size - The size of the common symbol.
/// @param ByteAlignment - The alignment of the symbol if
- /// non-zero. This must be a power of 2 on some targets.
- virtual void EmitCommonSymbol(MCSymbol *Symbol, unsigned Size,
+ /// non-zero. This must be a power of 2.
+ virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) = 0;
+ /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
+ ///
+ /// @param Symbol - The common symbol to emit.
+ /// @param Size - The size of the common symbol.
+ virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) = 0;
+
/// EmitZerofill - Emit a the zerofill section and an option symbol.
///
/// @param Section - The zerofill section to create and or to put the symbol
@@ -155,7 +162,7 @@ namespace llvm {
///
/// This is used to implement assembler directives such as .byte, .ascii,
/// etc.
- virtual void EmitBytes(StringRef Data) = 0;
+ virtual void EmitBytes(StringRef Data, unsigned AddrSpace) = 0;
/// EmitValue - Emit the expression @param Value into the output as a native
/// integer of the given @param Size bytes.
@@ -166,8 +173,25 @@ namespace llvm {
/// @param Value - The value to emit.
/// @param Size - The size of the integer (in bytes) to emit. This must
/// match a native machine width.
- virtual void EmitValue(const MCExpr *Value, unsigned Size) = 0;
+ virtual void EmitValue(const MCExpr *Value, unsigned Size,
+ unsigned AddrSpace) = 0;
+ /// EmitIntValue - Special case of EmitValue that avoids the client having
+ /// to pass in a MCExpr for constant integers.
+ virtual void EmitIntValue(uint64_t Value, unsigned Size,unsigned AddrSpace);
+
+ /// EmitFill - Emit NumBytes bytes worth of the value specified by
+ /// FillValue. This implements directives such as '.space'.
+ virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
+ unsigned AddrSpace);
+
+ /// EmitZeros - Emit NumBytes worth of zeros. This is a convenience
+ /// function that just wraps EmitFill.
+ void EmitZeros(uint64_t NumBytes, unsigned AddrSpace) {
+ EmitFill(NumBytes, 0, AddrSpace);
+ }
+
+
/// EmitValueToAlignment - Emit some number of copies of @param Value until
/// the byte alignment @param ByteAlignment is reached.
///
@@ -217,8 +241,9 @@ namespace llvm {
/// createAsmStreamer - Create a machine code streamer which will print out
/// assembly for the native target, suitable for compiling with a native
/// assembler.
- MCStreamer *createAsmStreamer(MCContext &Ctx, raw_ostream &OS,
- const MCAsmInfo &MAI,
+ MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+ const MCAsmInfo &MAI, bool isLittleEndian,
+ bool isVerboseAsm,
MCInstPrinter *InstPrint = 0,
MCCodeEmitter *CE = 0);
diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h
index eb59453..e770604 100644
--- a/include/llvm/MC/MCSymbol.h
+++ b/include/llvm/MC/MCSymbol.h
@@ -19,14 +19,14 @@
#include "llvm/System/DataTypes.h"
namespace llvm {
- class MCAsmInfo;
class MCExpr;
class MCSection;
class MCContext;
class raw_ostream;
/// MCSymbol - Instances of this class represent a symbol name in the MC file,
- /// and MCSymbols are created and unique'd by the MCContext class.
+ /// and MCSymbols are created and unique'd by the MCContext class. MCSymbols
+ /// should only be constructed with valid names for the object file.
///
/// If the symbol is defined/emitted into the current translation unit, the
/// Section member is set to indicate what section it lives in. Otherwise, if
@@ -53,7 +53,7 @@ namespace llvm {
/// typically does not survive in the .o file's symbol table. Usually
/// "Lfoo" or ".foo".
unsigned IsTemporary : 1;
-
+
private: // MCContext creates and uniques these.
friend class MCContext;
MCSymbol(StringRef _Name, bool _IsTemporary)
@@ -132,17 +132,16 @@ namespace llvm {
/// @}
/// print - Print the value to the stream \arg OS.
- void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
+ void print(raw_ostream &OS) const;
/// dump - Print the value to stderr.
void dump() const;
-
- /// printMangledName - Print the specified string in mangled form if it uses
- /// any unusual characters.
- static void printMangledName(StringRef Str, raw_ostream &OS,
- const MCAsmInfo *MAI);
};
+ inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) {
+ Sym.print(OS);
+ return OS;
+ }
} // end namespace llvm
#endif
diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h
index 4f5ab31..8aa73f3 100644
--- a/include/llvm/MC/MCValue.h
+++ b/include/llvm/MC/MCValue.h
@@ -20,6 +20,7 @@
namespace llvm {
class MCSymbol;
+class MCAsmInfo;
class raw_ostream;
/// MCValue - This represents an "assembler immediate". In its most general
diff --git a/include/llvm/MC/SectionKind.h b/include/llvm/MC/SectionKind.h
index 945cff7..c9557f2 100644
--- a/include/llvm/MC/SectionKind.h
+++ b/include/llvm/MC/SectionKind.h
@@ -87,6 +87,18 @@ class SectionKind {
/// BSS - Zero initialized writeable data.
BSS,
+
+ /// BSSLocal - This is BSS (zero initialized and writable) data
+ /// which has local linkage.
+ BSSLocal,
+
+ /// BSSExtern - This is BSS data with normal external linkage.
+ BSSExtern,
+
+ /// Common - Data with common linkage. These represent tentative
+ /// definitions, which always have a zero initializer and are never
+ /// marked 'constant'.
+ Common,
/// DataRel - This is the most general form of data that is written
/// to by the program, it can have random relocations to arbitrary
@@ -158,10 +170,14 @@ public:
bool isThreadData() const { return K == ThreadData; }
bool isGlobalWriteableData() const {
- return isBSS() || isDataRel() || isReadOnlyWithRel();
+ return isBSS() || isCommon() || isDataRel() || isReadOnlyWithRel();
}
- bool isBSS() const { return K == BSS; }
+ bool isBSS() const { return K == BSS || K == BSSLocal || K == BSSExtern; }
+ bool isBSSLocal() const { return K == BSSLocal; }
+ bool isBSSExtern() const { return K == BSSExtern; }
+
+ bool isCommon() const { return K == Common; }
bool isDataRel() const {
return K == DataRel || K == DataRelLocal || K == DataNoRel;
@@ -207,6 +223,9 @@ public:
static SectionKind getThreadBSS() { return get(ThreadBSS); }
static SectionKind getThreadData() { return get(ThreadData); }
static SectionKind getBSS() { return get(BSS); }
+ static SectionKind getBSSLocal() { return get(BSSLocal); }
+ static SectionKind getBSSExtern() { return get(BSSExtern); }
+ static SectionKind getCommon() { return get(Common); }
static SectionKind getDataRel() { return get(DataRel); }
static SectionKind getDataRelLocal() { return get(DataRelLocal); }
static SectionKind getDataNoRel() { return get(DataNoRel); }
diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h
index 179010b..f1e7a22 100644
--- a/include/llvm/Metadata.h
+++ b/include/llvm/Metadata.h
@@ -31,26 +31,10 @@ template<typename ValueSubClass, typename ItemParentClass>
//===----------------------------------------------------------------------===//
-// MetadataBase - A base class for MDNode and MDString.
-class MetadataBase : public Value {
-protected:
- MetadataBase(const Type *Ty, unsigned scid)
- : Value(Ty, scid) {}
-
-public:
-
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const MetadataBase *) { return true; }
- static bool classof(const Value *V) {
- return V->getValueID() == MDStringVal || V->getValueID() == MDNodeVal;
- }
-};
-
-//===----------------------------------------------------------------------===//
/// MDString - a single uniqued string.
/// These are used to efficiently contain a byte sequence for metadata.
/// MDString is always unnamd.
-class MDString : public MetadataBase {
+class MDString : public Value {
MDString(const MDString &); // DO NOT IMPLEMENT
StringRef Str;
@@ -87,7 +71,7 @@ class MDNodeOperand;
//===----------------------------------------------------------------------===//
/// MDNode - a tuple of other values.
-class MDNode : public MetadataBase, public FoldingSetNode {
+class MDNode : public Value, public FoldingSetNode {
MDNode(const MDNode &); // DO NOT IMPLEMENT
void operator=(const MDNode &); // DO NOT IMPLEMENT
friend class MDNodeOperand;
@@ -154,8 +138,9 @@ public:
// getFunction - If this metadata is function-local and recursively has a
// function-local operand, return the first such operand's parent function.
- // Otherwise, return null.
- Function *getFunction() const;
+ // Otherwise, return null. getFunction() should not be used for performance-
+ // critical code because it recursively visits all the MDNode's operands.
+ const Function *getFunction() const;
// destroy - Delete this node. Only when there are no uses.
void destroy();
diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h
index f3e4dfd..ab08afb 100644
--- a/include/llvm/Pass.h
+++ b/include/llvm/Pass.h
@@ -64,6 +64,16 @@ enum PassManagerType {
PMT_Last
};
+// Different types of passes.
+enum PassKind {
+ PT_BasicBlock,
+ PT_Loop,
+ PT_Function,
+ PT_CallGraphSCC,
+ PT_Module,
+ PT_PassManager
+};
+
//===----------------------------------------------------------------------===//
/// Pass interface - Implemented by all 'passes'. Subclass this if you are an
/// interprocedural optimization or you do not fit into any of the more
@@ -72,19 +82,23 @@ enum PassManagerType {
class Pass {
AnalysisResolver *Resolver; // Used to resolve analysis
intptr_t PassID;
-
+ PassKind Kind;
void operator=(const Pass&); // DO NOT IMPLEMENT
Pass(const Pass &); // DO NOT IMPLEMENT
public:
- explicit Pass(intptr_t pid) : Resolver(0), PassID(pid) {
+ explicit Pass(PassKind K, intptr_t pid) : Resolver(0), PassID(pid), Kind(K) {
assert(pid && "pid cannot be 0");
}
- explicit Pass(const void *pid) : Resolver(0), PassID((intptr_t)pid) {
+ explicit Pass(PassKind K, const void *pid)
+ : Resolver(0), PassID((intptr_t)pid), Kind(K) {
assert(pid && "pid cannot be 0");
}
virtual ~Pass();
+
+ PassKind getPassKind() const { return Kind; }
+
/// getPassName - Return a nice clean name for a pass. This usually
/// implemented in terms of the name that is registered by one of the
/// Registration templates, but can be overloaded directly.
@@ -118,7 +132,7 @@ public:
// Access AnalysisResolver
inline void setResolver(AnalysisResolver *AR) {
- assert (!Resolver && "Resolver is already set");
+ assert(!Resolver && "Resolver is already set");
Resolver = AR;
}
inline AnalysisResolver *getResolver() {
@@ -145,6 +159,16 @@ public:
///
virtual void releaseMemory();
+ /// getAdjustedAnalysisPointer - This method is used when a pass implements
+ /// an analysis interface through multiple inheritance. If needed, it should
+ /// override this to adjust the this pointer as needed for the specified pass
+ /// info.
+ virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+ return this;
+ }
+ virtual ImmutablePass *getAsImmutablePass() { return 0; }
+ virtual PMDataManager *getAsPMDataManager() { return 0; }
+
/// verifyAnalysis() - This member can be implemented by a analysis pass to
/// check state of analysis information.
virtual void verifyAnalysis() const;
@@ -219,8 +243,8 @@ public:
/// Return what kind of Pass Manager can manage this pass.
virtual PassManagerType getPotentialPassManagerType() const;
- explicit ModulePass(intptr_t pid) : Pass(pid) {}
- explicit ModulePass(const void *pid) : Pass(pid) {}
+ explicit ModulePass(intptr_t pid) : Pass(PT_Module, pid) {}
+ explicit ModulePass(const void *pid) : Pass(PT_Module, pid) {}
// Force out-of-line virtual method.
virtual ~ModulePass();
};
@@ -241,6 +265,8 @@ public:
///
virtual void initializePass();
+ virtual ImmutablePass *getAsImmutablePass() { return this; }
+
/// ImmutablePasses are never run.
///
bool runOnModule(Module &) { return false; }
@@ -264,8 +290,8 @@ public:
///
class FunctionPass : public Pass {
public:
- explicit FunctionPass(intptr_t pid) : Pass(pid) {}
- explicit FunctionPass(const void *pid) : Pass(pid) {}
+ explicit FunctionPass(intptr_t pid) : Pass(PT_Function, pid) {}
+ explicit FunctionPass(const void *pid) : Pass(PT_Function, pid) {}
/// doInitialization - Virtual method overridden by subclasses to do
/// any necessary per-module initialization.
@@ -314,8 +340,8 @@ public:
///
class BasicBlockPass : public Pass {
public:
- explicit BasicBlockPass(intptr_t pid) : Pass(pid) {}
- explicit BasicBlockPass(const void *pid) : Pass(pid) {}
+ explicit BasicBlockPass(intptr_t pid) : Pass(PT_BasicBlock, pid) {}
+ explicit BasicBlockPass(const void *pid) : Pass(PT_BasicBlock, pid) {}
/// doInitialization - Virtual method overridden by subclasses to do
/// any necessary per-module initialization.
diff --git a/include/llvm/PassAnalysisSupport.h b/include/llvm/PassAnalysisSupport.h
index 5864fad..d59be3c 100644
--- a/include/llvm/PassAnalysisSupport.h
+++ b/include/llvm/PassAnalysisSupport.h
@@ -19,15 +19,13 @@
#ifndef LLVM_PASS_ANALYSIS_SUPPORT_H
#define LLVM_PASS_ANALYSIS_SUPPORT_H
-#include <vector>
#include "llvm/Pass.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include <vector>
namespace llvm {
-class StringRef;
-
//===----------------------------------------------------------------------===//
// AnalysisUsage - Represent the analysis usage information of a pass. This
// tracks analyses that the pass REQUIRES (must be available when the pass
@@ -192,8 +190,15 @@ AnalysisType *Pass::getAnalysisIfAvailable() const {
const PassInfo *PI = getClassPassInfo<AnalysisType>();
if (PI == 0) return 0;
- return dynamic_cast<AnalysisType*>
- (Resolver->getAnalysisIfAvailable(PI, true));
+
+ Pass *ResultPass = Resolver->getAnalysisIfAvailable(PI, true);
+ if (ResultPass == 0) return 0;
+
+ // Because the AnalysisType may not be a subclass of pass (for
+ // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially
+ // adjust the return pointer (because the class may multiply inherit, once
+ // from pass, once from AnalysisType).
+ return (AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI);
}
/// getAnalysis<AnalysisType>() - This function is used by subclasses to get
@@ -202,8 +207,7 @@ AnalysisType *Pass::getAnalysisIfAvailable() const {
///
template<typename AnalysisType>
AnalysisType &Pass::getAnalysis() const {
- assert(Resolver &&"Pass has not been inserted into a PassManager object!");
-
+ assert(Resolver && "Pass has not been inserted into a PassManager object!");
return getAnalysisID<AnalysisType>(getClassPassInfo<AnalysisType>());
}
@@ -220,13 +224,10 @@ AnalysisType &Pass::getAnalysisID(const PassInfo *PI) const {
"'required' by pass!");
// Because the AnalysisType may not be a subclass of pass (for
- // AnalysisGroups), we must use dynamic_cast here to potentially adjust the
- // return pointer (because the class may multiply inherit, once from pass,
- // once from AnalysisType).
- //
- AnalysisType *Result = dynamic_cast<AnalysisType*>(ResultPass);
- assert(Result && "Pass does not implement interface required!");
- return *Result;
+ // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially
+ // adjust the return pointer (because the class may multiply inherit, once
+ // from pass, once from AnalysisType).
+ return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI);
}
/// getAnalysis<AnalysisType>() - This function is used by subclasses to get
@@ -248,16 +249,13 @@ AnalysisType &Pass::getAnalysisID(const PassInfo *PI, Function &F) {
// should be a small number, we just do a linear search over a (dense)
// vector.
Pass *ResultPass = Resolver->findImplPass(this, PI, F);
- assert (ResultPass && "Unable to find requested analysis info");
+ assert(ResultPass && "Unable to find requested analysis info");
// Because the AnalysisType may not be a subclass of pass (for
- // AnalysisGroups), we must use dynamic_cast here to potentially adjust the
- // return pointer (because the class may multiply inherit, once from pass,
- // once from AnalysisType).
- //
- AnalysisType *Result = dynamic_cast<AnalysisType*>(ResultPass);
- assert(Result && "Pass does not implement interface required!");
- return *Result;
+ // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially
+ // adjust the return pointer (because the class may multiply inherit, once
+ // from pass, once from AnalysisType).
+ return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI);
}
} // End llvm namespace
diff --git a/include/llvm/PassManagers.h b/include/llvm/PassManagers.h
index dffc24a..443a9e0 100644
--- a/include/llvm/PassManagers.h
+++ b/include/llvm/PassManagers.h
@@ -273,6 +273,8 @@ public:
}
virtual ~PMDataManager();
+
+ virtual Pass *getAsPass() = 0;
/// Augment AvailableAnalysis by adding analysis made available by pass P.
void recordAvailableAnalysis(Pass *P);
@@ -413,7 +415,6 @@ private:
/// function.
class FPPassManager : public ModulePass, public PMDataManager {
-
public:
static char ID;
explicit FPPassManager(int Depth)
@@ -435,6 +436,9 @@ public:
///
bool doFinalization(Module &M);
+ virtual PMDataManager *getAsPMDataManager() { return this; }
+ virtual Pass *getAsPass() { return this; }
+
/// Pass Manager itself does not invalidate any analysis info.
void getAnalysisUsage(AnalysisUsage &Info) const {
Info.setPreservesAll();
diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h
index d7f3097..b229989 100644
--- a/include/llvm/PassSupport.h
+++ b/include/llvm/PassSupport.h
@@ -82,6 +82,11 @@ public:
/// TODO : Rename
intptr_t getTypeInfo() const { return PassID; }
+ /// Return true if this PassID implements the specified ID pointer.
+ bool isPassID(void *IDPtr) const {
+ return PassID == (intptr_t)IDPtr;
+ }
+
/// isAnalysisGroup - Return true if this is an analysis group, not a normal
/// pass.
///
diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h
index 90b95bf..3875f0b 100644
--- a/include/llvm/Support/CFG.h
+++ b/include/llvm/Support/CFG.h
@@ -149,8 +149,8 @@ public:
}
inline bool operator>(const _Self& x) const {
- return idx > x.idx;
assert(Term == x.Term && "Cannot compare iterators of different blocks!");
+ return idx > x.idx;
}
inline _Self& operator+=(int Right) {
diff --git a/include/llvm/Support/DebugLoc.h b/include/llvm/Support/DebugLoc.h
index 6814f63..32631fc 100644
--- a/include/llvm/Support/DebugLoc.h
+++ b/include/llvm/Support/DebugLoc.h
@@ -21,29 +21,6 @@
namespace llvm {
class MDNode;
- /// DebugLocTuple - Debug location tuple of filename id, line and column.
- ///
- struct DebugLocTuple {
- MDNode *Scope;
- MDNode *InlinedAtLoc;
- unsigned Line, Col;
-
- DebugLocTuple()
- : Scope(0), InlinedAtLoc(0), Line(~0U), Col(~0U) {}
-
- DebugLocTuple(MDNode *n, MDNode *i, unsigned l, unsigned c)
- : Scope(n), InlinedAtLoc(i), Line(l), Col(c) {}
-
- bool operator==(const DebugLocTuple &DLT) const {
- return Scope == DLT.Scope &&
- InlinedAtLoc == DLT.InlinedAtLoc &&
- Line == DLT.Line && Col == DLT.Col;
- }
- bool operator!=(const DebugLocTuple &DLT) const {
- return !(*this == DLT);
- }
- };
-
/// DebugLoc - Debug location id. This is carried by SDNode and MachineInstr
/// to index into a vector of unique debug location tuples.
class DebugLoc {
@@ -65,40 +42,16 @@ namespace llvm {
bool operator!=(const DebugLoc &DL) const { return !(*this == DL); }
};
- // Specialize DenseMapInfo for DebugLocTuple.
- template<> struct DenseMapInfo<DebugLocTuple> {
- static inline DebugLocTuple getEmptyKey() {
- return DebugLocTuple(0, 0, ~0U, ~0U);
- }
- static inline DebugLocTuple getTombstoneKey() {
- return DebugLocTuple((MDNode*)~1U, (MDNode*)~1U, ~1U, ~1U);
- }
- static unsigned getHashValue(const DebugLocTuple &Val) {
- return DenseMapInfo<MDNode*>::getHashValue(Val.Scope) ^
- DenseMapInfo<MDNode*>::getHashValue(Val.InlinedAtLoc) ^
- DenseMapInfo<unsigned>::getHashValue(Val.Line) ^
- DenseMapInfo<unsigned>::getHashValue(Val.Col);
- }
- static bool isEqual(const DebugLocTuple &LHS, const DebugLocTuple &RHS) {
- return LHS.Scope == RHS.Scope &&
- LHS.InlinedAtLoc == RHS.InlinedAtLoc &&
- LHS.Line == RHS.Line &&
- LHS.Col == RHS.Col;
- }
- };
- template <> struct isPodLike<DebugLocTuple> {static const bool value = true;};
-
-
- /// DebugLocTracker - This class tracks debug location information.
+ /// DebugLocTracker - This class tracks debug location information.
///
struct DebugLocTracker {
/// DebugLocations - A vector of unique DebugLocTuple's.
///
- std::vector<DebugLocTuple> DebugLocations;
+ std::vector<MDNode *> DebugLocations;
/// DebugIdMap - This maps DebugLocTuple's to indices into the
/// DebugLocations vector.
- DenseMap<DebugLocTuple, unsigned> DebugIdMap;
+ DenseMap<MDNode *, unsigned> DebugIdMap;
DebugLocTracker() {}
};
diff --git a/include/llvm/Support/Mangler.h b/include/llvm/Support/Mangler.h
deleted file mode 100644
index aa230d4..0000000
--- a/include/llvm/Support/Mangler.h
+++ /dev/null
@@ -1,142 +0,0 @@
-//===-- llvm/Support/Mangler.h - Self-contained name mangler ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Unified name mangler for various backends.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_MANGLER_H
-#define LLVM_SUPPORT_MANGLER_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include <string>
-
-namespace llvm {
-class Twine;
-class Type;
-class Module;
-class Value;
-class GlobalValue;
-template <typename T> class SmallVectorImpl;
-
-class Mangler {
-public:
- enum ManglerPrefixTy {
- Default, ///< Emit default string before each symbol.
- Private, ///< Emit "private" prefix before each symbol.
- LinkerPrivate ///< Emit "linker private" prefix before each symbol.
- };
-
-private:
- /// Prefix - This string is added to each symbol that is emitted, unless the
- /// symbol is marked as not needing this prefix.
- const char *Prefix;
-
- /// PrivatePrefix - This string is emitted before each symbol with private
- /// linkage.
- const char *PrivatePrefix;
-
- /// LinkerPrivatePrefix - This string is emitted before each symbol with
- /// "linker_private" linkage.
- const char *LinkerPrivatePrefix;
-
- /// UseQuotes - If this is set, the target accepts global names in quotes,
- /// e.g. "foo bar" is a legal name. This syntax is used instead of escaping
- /// the space character. By default, this is false.
- bool UseQuotes;
-
- /// SymbolsCanStartWithDigit - If this is set, the target allows symbols to
- /// start with digits (e.g., "0x0021"). By default, this is false.
- bool SymbolsCanStartWithDigit;
-
- /// 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
- /// ones.
- ///
- DenseMap<const GlobalValue*, unsigned> AnonGlobalIDs;
-
- /// NextAnonGlobalID - This simple counter is used to unique value names.
- ///
- unsigned NextAnonGlobalID;
-
- /// AcceptableChars - This bitfield contains a one for each character that is
- /// allowed to be part of an unmangled name.
- unsigned AcceptableChars[256 / 32];
-
-public:
- // Mangler ctor - if a prefix is specified, it will be prepended onto all
- // symbols.
- Mangler(Module &M, const char *Prefix = "", const char *privatePrefix = "",
- const char *linkerPrivatePrefix = "");
-
- /// setUseQuotes - If UseQuotes is set to true, this target accepts quoted
- /// strings for assembler labels.
- void setUseQuotes(bool Val) { UseQuotes = Val; }
-
- /// setSymbolsCanStartWithDigit - If SymbolsCanStartWithDigit is set to true,
- /// this target allows symbols to start with digits.
- void setSymbolsCanStartWithDigit(bool Val) { SymbolsCanStartWithDigit = Val; }
-
- /// Acceptable Characters - This allows the target to specify which characters
- /// are acceptable to the assembler without being mangled. By default we
- /// allow letters, numbers, '_', '$', '.', which is what GAS accepts, and '@'.
- void markCharAcceptable(unsigned char X) {
- AcceptableChars[X/32] |= 1 << (X&31);
- }
- void markCharUnacceptable(unsigned char X) {
- AcceptableChars[X/32] &= ~(1 << (X&31));
- }
- bool isCharAcceptable(unsigned char X) const {
- return (AcceptableChars[X/32] & (1 << (X&31))) != 0;
- }
-
- /// getMangledName - Returns the mangled name of V, an LLVM Value,
- /// in the current module. If 'Suffix' is specified, the name ends with the
- /// specified suffix. If 'ForcePrivate' is specified, the label is specified
- /// to have a private label prefix.
- ///
- /// FIXME: This is deprecated, new code should use getNameWithPrefix and use
- /// MCSymbol printing to handle quotes or not etc.
- ///
- std::string getMangledName(const GlobalValue *V, const char *Suffix = "",
- bool ForcePrivate = false);
-
- /// 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.
- void getNameWithPrefix(SmallVectorImpl<char> &OutName, const Twine &GVName,
- ManglerPrefixTy PrefixTy = Mangler::Default);
-
-private:
- /// makeNameProper - We don't want identifier names with ., space, or
- /// - in them, so we mangle these characters into the strings "d_",
- /// "s_", and "D_", respectively. This is a very simple mangling that
- /// doesn't guarantee unique names for values. getValueName already
- /// does this for you, so there's no point calling it on the result
- /// from getValueName.
- ///
- /// FIXME: This is deprecated, new code should use getNameWithPrefix and use
- /// MCSymbol printing to handle quotes or not etc.
- ///
- void makeNameProper(SmallVectorImpl<char> &OutName,
- const Twine &Name,
- ManglerPrefixTy PrefixTy = Mangler::Default);
-
-};
-
-} // End llvm namespace
-
-#endif // LLVM_SUPPORT_MANGLER_H
diff --git a/include/llvm/Support/PassNameParser.h b/include/llvm/Support/PassNameParser.h
index ea4fe01..cdca978 100644
--- a/include/llvm/Support/PassNameParser.h
+++ b/include/llvm/Support/PassNameParser.h
@@ -41,7 +41,9 @@ class PassNameParser : public PassRegistrationListener,
cl::Option *Opt;
public:
PassNameParser() : Opt(0) {}
-
+ virtual ~PassNameParser();
+
+
void initialize(cl::Option &O) {
Opt = &O;
cl::parser<const PassInfo*>::initialize(O);
diff --git a/include/llvm/Support/SMLoc.h b/include/llvm/Support/SMLoc.h
new file mode 100644
index 0000000..967bf14
--- /dev/null
+++ b/include/llvm/Support/SMLoc.h
@@ -0,0 +1,44 @@
+//===- SMLoc.h - Source location for use with diagnostics -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SMLoc class. This class encapsulates a location in
+// source code for use in diagnostics.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUPPORT_SMLOC_H
+#define SUPPORT_SMLOC_H
+
+namespace llvm {
+
+// SMLoc - Represents a location in source code.
+class SMLoc {
+ const char *Ptr;
+public:
+ SMLoc() : Ptr(0) {}
+ SMLoc(const SMLoc &RHS) : Ptr(RHS.Ptr) {}
+
+ bool isValid() const { return Ptr != 0; }
+
+ bool operator==(const SMLoc &RHS) const { return RHS.Ptr == Ptr; }
+ bool operator!=(const SMLoc &RHS) const { return RHS.Ptr != Ptr; }
+
+ const char *getPointer() const { return Ptr; }
+
+ static SMLoc getFromPointer(const char *Ptr) {
+ SMLoc L;
+ L.Ptr = Ptr;
+ return L;
+ }
+};
+
+}
+
+#endif
+
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
index b695ff1..5433a00 100644
--- a/include/llvm/Support/SourceMgr.h
+++ b/include/llvm/Support/SourceMgr.h
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file declares the SMLoc, SMDiagnostic and SourceMgr classes. This
+// This file declares the SMDiagnostic and SourceMgr classes. This
// provides a simple substrate for diagnostics, #include handling, and other low
// level things for simple parsers.
//
@@ -16,6 +16,8 @@
#ifndef SUPPORT_SOURCEMGR_H
#define SUPPORT_SOURCEMGR_H
+#include "llvm/Support/SMLoc.h"
+
#include <string>
#include <vector>
#include <cassert>
@@ -25,26 +27,6 @@ namespace llvm {
class SourceMgr;
class SMDiagnostic;
class raw_ostream;
-
-class SMLoc {
- const char *Ptr;
-public:
- SMLoc() : Ptr(0) {}
- SMLoc(const SMLoc &RHS) : Ptr(RHS.Ptr) {}
-
- bool isValid() const { return Ptr != 0; }
-
- bool operator==(const SMLoc &RHS) const { return RHS.Ptr == Ptr; }
- bool operator!=(const SMLoc &RHS) const { return RHS.Ptr != Ptr; }
-
- const char *getPointer() const { return Ptr; }
-
- static SMLoc getFromPointer(const char *Ptr) {
- SMLoc L;
- L.Ptr = Ptr;
- return L;
- }
-};
/// SourceMgr - This owns the files read by a parser, handles include stacks,
/// and handles diagnostic wrangling.
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index d3c45c2..0f227cc 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -456,6 +456,11 @@ public:
explicit raw_svector_ostream(SmallVectorImpl<char> &O);
~raw_svector_ostream();
+ /// resync - This is called when the SmallVector we're appending to is changed
+ /// outside of the raw_svector_ostream's control. It is only safe to do this
+ /// if the raw_svector_ostream has previously been flushed.
+ void resync();
+
/// str - Flushes the stream contents to the target vector and return a
/// StringRef for the vector contents.
StringRef str();
diff --git a/include/llvm/System/Host.h b/include/llvm/System/Host.h
index 6de1a4a..4fbf5c1 100644
--- a/include/llvm/System/Host.h
+++ b/include/llvm/System/Host.h
@@ -14,6 +14,7 @@
#ifndef LLVM_SYSTEM_HOST_H
#define LLVM_SYSTEM_HOST_H
+#include "llvm/ADT/StringMap.h"
#include <string>
namespace llvm {
@@ -47,6 +48,18 @@ namespace sys {
///
/// \return - The host CPU name, or empty if the CPU could not be determined.
std::string getHostCPUName();
+
+ /// getHostCPUFeatures - Get the LLVM names for the host CPU features.
+ /// The particular format of the names are target dependent, and suitable for
+ /// passing as -mattr to the target which matches the host.
+ ///
+ /// \param Features - A string mapping feature names to either
+ /// true (if enabled) or false (if disabled). This routine makes no guarantees
+ /// about exactly which features may appear in this map, except that they are
+ /// all valid LLVM feature names.
+ ///
+ /// \return - True on success.
+ bool getHostCPUFeatures(StringMap<bool> &Features);
}
}
diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h
new file mode 100644
index 0000000..04de4e9
--- /dev/null
+++ b/include/llvm/Target/Mangler.h
@@ -0,0 +1,75 @@
+//===-- llvm/Support/Mangler.h - Self-contained name mangler ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Unified name mangler for various backends.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MANGLER_H
+#define LLVM_SUPPORT_MANGLER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include <string>
+
+namespace llvm {
+class StringRef;
+class Twine;
+class Value;
+class GlobalValue;
+template <typename T> class SmallVectorImpl;
+class MCAsmInfo;
+
+class Mangler {
+public:
+ enum ManglerPrefixTy {
+ Default, ///< Emit default string before each symbol.
+ Private, ///< Emit "private" prefix before each symbol.
+ LinkerPrivate ///< Emit "linker private" prefix before each symbol.
+ };
+
+private:
+ const MCAsmInfo &MAI;
+
+ /// 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
+ /// ones.
+ ///
+ DenseMap<const GlobalValue*, unsigned> AnonGlobalIDs;
+
+ /// NextAnonGlobalID - This simple counter is used to unique value names.
+ ///
+ unsigned NextAnonGlobalID;
+
+public:
+ // Mangler ctor - if a prefix is specified, it will be prepended onto all
+ // symbols.
+ Mangler(const MCAsmInfo &mai) : MAI(mai), NextAnonGlobalID(1) {}
+
+ /// 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.
+ void getNameWithPrefix(SmallVectorImpl<char> &OutName, const Twine &GVName,
+ ManglerPrefixTy PrefixTy = Mangler::Default);
+
+ /// getNameWithPrefix - Return 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.
+ std::string getNameWithPrefix(const GlobalValue *GV,
+ bool isImplicitlyPrivate = false);
+};
+
+} // End llvm namespace
+
+#endif // LLVM_SUPPORT_MANGLER_H
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 206e42e..354e743 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -479,7 +479,7 @@ def COPY_TO_REGCLASS : Instruction {
}
def DEBUG_VALUE : Instruction {
let OutOperandList = (ops);
- let InOperandList = (ops unknown:$value, i64imm:$offset, unknown:$meta);
+ let InOperandList = (ops variable_ops);
let AsmString = "DEBUG_VALUE";
let Namespace = "TargetInstrInfo";
let isAsCheapAsAMove = 1;
diff --git a/include/llvm/Target/TargetAsmLexer.h b/include/llvm/Target/TargetAsmLexer.h
new file mode 100644
index 0000000..daba1ba
--- /dev/null
+++ b/include/llvm/Target/TargetAsmLexer.h
@@ -0,0 +1,79 @@
+//===-- llvm/Target/TargetAsmLexer.h - Target Assembly Lexer ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETASMLEXER_H
+#define LLVM_TARGET_TARGETASMLEXER_H
+
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+
+namespace llvm {
+class Target;
+
+/// TargetAsmLexer - Generic interface to target specific assembly lexers.
+class TargetAsmLexer {
+ /// The current token
+ AsmToken CurTok;
+
+ /// The location and description of the current error
+ SMLoc ErrLoc;
+ std::string Err;
+
+ TargetAsmLexer(const TargetAsmLexer &); // DO NOT IMPLEMENT
+ void operator=(const TargetAsmLexer &); // DO NOT IMPLEMENT
+protected: // Can only create subclasses.
+ TargetAsmLexer(const Target &);
+
+ virtual AsmToken LexToken() = 0;
+
+ void SetError(const SMLoc &errLoc, const std::string &err) {
+ ErrLoc = errLoc;
+ Err = err;
+ }
+
+ /// TheTarget - The Target that this machine was created for.
+ const Target &TheTarget;
+
+public:
+ virtual ~TargetAsmLexer();
+
+ const Target &getTarget() const { return TheTarget; }
+
+ /// Lex - Consume the next token from the input stream and return it.
+ const AsmToken &Lex() {
+ return CurTok = LexToken();
+ }
+
+ /// getTok - Get the current (last) lexed token.
+ const AsmToken &getTok() {
+ return CurTok;
+ }
+
+ /// getErrLoc - Get the current error location
+ const SMLoc &getErrLoc() {
+ return ErrLoc;
+ }
+
+ /// getErr - Get the current error string
+ const std::string &getErr() {
+ return Err;
+ }
+
+ /// getKind - Get the kind of current token.
+ AsmToken::TokenKind getKind() const { return CurTok.getKind(); }
+
+ /// is - Check if the current token has kind \arg K.
+ bool is(AsmToken::TokenKind K) const { return CurTok.is(K); }
+
+ /// isNot - Check if the current token has kind \arg K.
+ bool isNot(AsmToken::TokenKind K) const { return CurTok.isNot(K); }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetAsmParser.h b/include/llvm/Target/TargetAsmParser.h
index 1d3da8b..da9ba2b 100644
--- a/include/llvm/Target/TargetAsmParser.h
+++ b/include/llvm/Target/TargetAsmParser.h
@@ -11,7 +11,6 @@
#define LLVM_TARGET_TARGETPARSER_H
namespace llvm {
-class MCAsmParser;
class MCInst;
class StringRef;
class Target;
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index 8e2157e..7144fe0 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -486,6 +486,30 @@ public:
unsigned *LoadRegIndex = 0) const {
return 0;
}
+
+ /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler
+ /// to determine if two loads are loading from the same base address. It
+ /// should only return true if the base pointers are the same and the
+ /// only differences between the two addresses are the offset. It also returns
+ /// the offsets by reference.
+ virtual bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
+ int64_t &Offset1, int64_t &Offset2) const {
+ return false;
+ }
+
+ /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to
+ /// determine (in conjuction with areLoadsFromSameBasePtr) if two loads should
+ /// be scheduled togther. On some targets if two loads are loading from
+ /// addresses in the same cache line, it's better if they are scheduled
+ /// together. This function takes two integers that represent the load offsets
+ /// from the common base address. It returns true if it decides it's desirable
+ /// to schedule the two loads together. "NumLoads" is the number of loads that
+ /// have already been scheduled after Load1.
+ virtual bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
+ int64_t Offset1, int64_t Offset2,
+ unsigned NumLoads) const {
+ return false;
+ }
/// ReverseBranchCondition - Reverses the branch condition of the specified
/// condition list, returning false on success and true if it cannot be
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index 3dd7471..d3e5cf2 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -258,6 +258,8 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
const MCSection *ConstDataCoalSection;
const MCSection *ConstDataSection;
const MCSection *DataCoalSection;
+ const MCSection *DataCommonSection;
+ const MCSection *DataBSSSection;
const MCSection *FourByteConstantSection;
const MCSection *EightByteConstantSection;
const MCSection *SixteenByteConstantSection;
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 84cd5b4..4db3d3e 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -81,6 +81,14 @@ namespace CodeGenOpt {
};
}
+// Specify if we should encode the LSDA pointer in the FDE as 4- or 8-bytes.
+namespace DwarfLSDAEncoding {
+ enum Encoding {
+ Default,
+ FourByte,
+ EightByte
+ };
+}
//===----------------------------------------------------------------------===//
///
@@ -129,10 +137,7 @@ public:
/// TargetSubtarget. In debug builds, it verifies that the object being
/// returned is of the correct type.
template<typename STC> const STC &getSubtarget() const {
- const TargetSubtarget *TST = getSubtargetImpl();
- assert(TST && dynamic_cast<const STC*>(TST) &&
- "Not the right kind of subtarget!");
- return *static_cast<const STC*>(TST);
+ return *static_cast<const STC*>(getSubtargetImpl());
}
/// getRegisterInfo - If register information is available, return it. If
@@ -192,6 +197,20 @@ public:
/// is false.
static void setAsmVerbosityDefault(bool);
+ /// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are
+ /// 4-byte, 8-byte, and target default. The CIE is hard-coded to indicate that
+ /// the LSDA pointer in the FDE section is an "sdata4", and should be encoded
+ /// as a 4-byte pointer by default. However, some systems may require a
+ /// different size due to bugs or other conditions. We will default to a
+ /// 4-byte encoding unless the system tells us otherwise.
+ ///
+ /// FIXME: This call-back isn't good! We should be using the correct encoding
+ /// regardless of the system. However, there are some systems which have bugs
+ /// that prevent this from occuring.
+ virtual DwarfLSDAEncoding::Encoding getLSDAEncoding() const {
+ return DwarfLSDAEncoding::Default;
+ }
+
/// CodeGenFileType - These enums are meant to be passed into
/// addPassesToEmitFile to indicate what type of file to emit.
enum CodeGenFileType {
@@ -452,6 +471,14 @@ public:
bool addAssemblyEmitter(PassManagerBase &, CodeGenOpt::Level,
bool /* VerboseAsmDefault */,
formatted_raw_ostream &);
+
+ /// addObjectFileEmitter - Helper function which creates a target specific
+ /// object files emitter, if available. This interface is temporary, for
+ /// bringing up MCAssembler-based object file emitters.
+ ///
+ /// \return Returns 'false' on success.
+ bool addObjectFileEmitter(PassManagerBase &, CodeGenOpt::Level,
+ formatted_raw_ostream &);
};
} // End llvm namespace
diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h
index 167e1d1..d3aa867 100644
--- a/include/llvm/Target/TargetRegistry.h
+++ b/include/llvm/Target/TargetRegistry.h
@@ -31,6 +31,7 @@ namespace llvm {
class MCAsmInfo;
class MCDisassembler;
class MCInstPrinter;
+ class TargetAsmLexer;
class TargetAsmParser;
class TargetMachine;
class formatted_raw_ostream;
@@ -59,8 +60,9 @@ namespace llvm {
TargetMachine &TM,
const MCAsmInfo *MAI,
bool VerboseAsm);
- typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,
- MCAsmParser &P);
+ typedef TargetAsmLexer *(*AsmLexerCtorTy)(const Target &T,
+ const MCAsmInfo &MAI);
+ typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,MCAsmParser &P);
typedef const MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T);
typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
unsigned SyntaxVariant,
@@ -97,8 +99,12 @@ namespace llvm {
/// if registered.
AsmPrinterCtorTy AsmPrinterCtorFn;
- /// AsmParserCtorFn - Construction function for this target's AsmParser,
+ /// AsmLexerCtorFn - Construction function for this target's TargetAsmLexer,
/// if registered.
+ AsmLexerCtorTy AsmLexerCtorFn;
+
+ /// AsmParserCtorFn - Construction function for this target's
+ /// TargetAsmParser, if registered.
AsmParserCtorTy AsmParserCtorFn;
/// MCDisassemblerCtorFn - Construction function for this target's
@@ -191,6 +197,14 @@ namespace llvm {
return AsmPrinterCtorFn(OS, TM, MAI, Verbose);
}
+ /// createAsmLexer - Create a target specific assembly lexer.
+ ///
+ TargetAsmLexer *createAsmLexer(const MCAsmInfo &MAI) const {
+ if (!AsmLexerCtorFn)
+ return 0;
+ return AsmLexerCtorFn(*this, MAI);
+ }
+
/// createAsmParser - Create a target specific assembly parser.
///
/// \arg Parser - The target independent parser implementation to use for
@@ -358,6 +372,20 @@ namespace llvm {
T.AsmPrinterCtorFn = Fn;
}
+ /// RegisterAsmLexer - Register a TargetAsmLexer implementation for the
+ /// given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct an AsmPrinter for the target.
+ static void RegisterAsmLexer(Target &T, Target::AsmLexerCtorTy Fn) {
+ if (!T.AsmLexerCtorFn)
+ T.AsmLexerCtorFn = Fn;
+ }
+
/// RegisterAsmParser - Register a TargetAsmParser implementation for the
/// given target.
///
@@ -524,6 +552,26 @@ namespace llvm {
}
};
+ /// RegisterAsmLexer - Helper template for registering a target specific
+ /// assembly lexer, for use in the target machine initialization
+ /// function. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooAsmLexer() {
+ /// extern Target TheFooTarget;
+ /// RegisterAsmLexer<FooAsmLexer> X(TheFooTarget);
+ /// }
+ template<class AsmLexerImpl>
+ struct RegisterAsmLexer {
+ RegisterAsmLexer(Target &T) {
+ TargetRegistry::RegisterAsmLexer(T, &Allocator);
+ }
+
+ private:
+ static TargetAsmLexer *Allocator(const Target &T, const MCAsmInfo &MAI) {
+ return new AsmLexerImpl(T, MAI);
+ }
+ };
+
/// RegisterAsmParser - Helper template for registering a target specific
/// assembly parser, for use in the target machine initialization
/// function. Usage:
diff --git a/include/llvm/Transforms/IPO/InlinerPass.h b/include/llvm/Transforms/IPO/InlinerPass.h
index 5d00f42..dc5e644 100644
--- a/include/llvm/Transforms/IPO/InlinerPass.h
+++ b/include/llvm/Transforms/IPO/InlinerPass.h
@@ -51,6 +51,12 @@ struct Inliner : public CallGraphSCCPass {
///
unsigned getInlineThreshold() const { return InlineThreshold; }
+ /// Calculate the inline threshold for given Caller. This threshold is lower
+ /// if Caller is marked with OptimizeForSize and -inline-threshold is not
+ /// given on the comand line.
+ ///
+ unsigned getInlineThreshold(Function* Caller) const;
+
/// getInlineCost - This method must be implemented by the subclass to
/// determine the cost of inlining the specified call site. If the cost
/// returned is greater than the current inline threshold, the call site is
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
index 0b8147e..f6d9f82 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -27,7 +27,6 @@ class PHINode;
class AllocaInst;
class ConstantExpr;
class TargetData;
-class DbgInfoIntrinsic;
template<typename T> class SmallVectorImpl;
@@ -154,12 +153,6 @@ AllocaInst *DemoteRegToStack(Instruction &X,
/// The phi node is deleted and it returns the pointer to the alloca inserted.
AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = 0);
-/// OnlyUsedByDbgIntrinsics - Return true if the instruction I is only used
-/// by DbgIntrinsics. If DbgInUses is specified then the vector is filled
-/// with DbgInfoIntrinsic that use the instruction I.
-bool OnlyUsedByDbgInfoIntrinsics(Instruction *I,
- SmallVectorImpl<DbgInfoIntrinsic *> *DbgInUses = 0);
-
} // End llvm namespace
#endif
diff --git a/lib/Analysis/AliasAnalysisCounter.cpp b/lib/Analysis/AliasAnalysisCounter.cpp
index ae28b55..761cd46 100644
--- a/lib/Analysis/AliasAnalysisCounter.cpp
+++ b/lib/Analysis/AliasAnalysisCounter.cpp
@@ -31,7 +31,6 @@ namespace {
class AliasAnalysisCounter : public ModulePass, public AliasAnalysis {
unsigned No, May, Must;
unsigned NoMR, JustRef, JustMod, MR;
- const char *Name;
Module *M;
public:
static char ID; // Class identification, replacement for typeinfo
@@ -49,7 +48,7 @@ namespace {
unsigned MRSum = NoMR+JustRef+JustMod+MR;
if (AASum + MRSum) { // Print a report if any counted queries occurred...
errs() << "\n===== Alias Analysis Counter Report =====\n"
- << " Analysis counted: " << Name << "\n"
+ << " Analysis counted:\n"
<< " " << AASum << " Total Alias Queries Performed\n";
if (AASum) {
printLine("no alias", No, AASum);
@@ -75,7 +74,6 @@ namespace {
bool runOnModule(Module &M) {
this->M = &M;
InitializeAliasAnalysis(this);
- Name = dynamic_cast<Pass*>(&getAnalysis<AliasAnalysis>())->getPassName();
return false;
}
@@ -85,6 +83,16 @@ namespace {
AU.setPreservesAll();
}
+ /// getAdjustedAnalysisPointer - This method is used when a pass implements
+ /// an analysis interface through multiple inheritance. If needed, it
+ /// should override this to adjust the this pointer as needed for the
+ /// specified pass info.
+ virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+ if (PI->isPassID(&AliasAnalysis::ID))
+ return (AliasAnalysis*)this;
+ return this;
+ }
+
// FIXME: We could count these too...
bool pointsToConstantMemory(const Value *P) {
return getAnalysis<AliasAnalysis>().pointsToConstantMemory(P);
diff --git a/lib/Analysis/AliasDebugger.cpp b/lib/Analysis/AliasDebugger.cpp
index 6868e3f..88c2875 100644
--- a/lib/Analysis/AliasDebugger.cpp
+++ b/lib/Analysis/AliasDebugger.cpp
@@ -71,6 +71,16 @@ namespace {
AU.setPreservesAll(); // Does not transform code
}
+ /// getAdjustedAnalysisPointer - This method is used when a pass implements
+ /// an analysis interface through multiple inheritance. If needed, it
+ /// should override this to adjust the this pointer as needed for the
+ /// specified pass info.
+ virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+ if (PI->isPassID(&AliasAnalysis::ID))
+ return (AliasAnalysis*)this;
+ return this;
+ }
+
//------------------------------------------------
// Implement the AliasAnalysis API
//
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp
index b2983c7..36b831c 100644
--- a/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/lib/Analysis/BasicAliasAnalysis.cpp
@@ -153,6 +153,16 @@ namespace {
virtual void deleteValue(Value *V) {}
virtual void copyValue(Value *From, Value *To) {}
+
+ /// getAdjustedAnalysisPointer - This method is used when a pass implements
+ /// an analysis interface through multiple inheritance. If needed, it should
+ /// override this to adjust the this pointer as needed for the specified pass
+ /// info.
+ virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+ if (PI->isPassID(&AliasAnalysis::ID))
+ return (AliasAnalysis*)this;
+ return this;
+ }
};
} // End of anonymous namespace
@@ -192,6 +202,16 @@ namespace {
/// global) or not.
bool pointsToConstantMemory(const Value *P);
+ /// getAdjustedAnalysisPointer - This method is used when a pass implements
+ /// an analysis interface through multiple inheritance. If needed, it should
+ /// override this to adjust the this pointer as needed for the specified pass
+ /// info.
+ virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+ if (PI->isPassID(&AliasAnalysis::ID))
+ return (AliasAnalysis*)this;
+ return this;
+ }
+
private:
// VisitedPHIs - Track PHI nodes visited by a aliasCheck() call.
SmallPtrSet<const Value*, 16> VisitedPHIs;
diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp
index 59ba807..4ba837a 100644
--- a/lib/Analysis/DebugInfo.cpp
+++ b/lib/Analysis/DebugInfo.cpp
@@ -599,7 +599,7 @@ void DIVariable::dump() const {
//===----------------------------------------------------------------------===//
DIFactory::DIFactory(Module &m)
- : M(m), VMContext(M.getContext()), DeclareFn(0) {}
+ : M(m), VMContext(M.getContext()), DeclareFn(0), ValueFn(0) {}
Constant *DIFactory::GetTagConstant(unsigned TAG) {
assert((TAG & LLVMDebugVersionMask) == 0 &&
@@ -854,7 +854,7 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
StringRef DisplayName,
StringRef LinkageName,
DICompileUnit CompileUnit,
- unsigned LineNo, DIType Type,
+ unsigned LineNo, DIType Ty,
bool isLocalToUnit,
bool isDefinition,
unsigned VK, unsigned VIndex,
@@ -869,7 +869,7 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
MDString::get(VMContext, LinkageName),
CompileUnit.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
- Type.getNode(),
+ Ty.getNode(),
ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit),
ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition),
ConstantInt::get(Type::getInt32Ty(VMContext), (unsigned)VK),
@@ -911,7 +911,7 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, StringRef Name,
StringRef DisplayName,
StringRef LinkageName,
DICompileUnit CompileUnit,
- unsigned LineNo, DIType Type,bool isLocalToUnit,
+ unsigned LineNo, DIType Ty,bool isLocalToUnit,
bool isDefinition, llvm::GlobalVariable *Val) {
Value *Elts[] = {
GetTagConstant(dwarf::DW_TAG_variable),
@@ -922,7 +922,7 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, StringRef Name,
MDString::get(VMContext, LinkageName),
CompileUnit.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
- Type.getNode(),
+ Ty.getNode(),
ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit),
ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition),
Val
@@ -943,14 +943,14 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, StringRef Name,
DIVariable DIFactory::CreateVariable(unsigned Tag, DIDescriptor Context,
StringRef Name,
DICompileUnit CompileUnit, unsigned LineNo,
- DIType Type) {
+ DIType Ty) {
Value *Elts[] = {
GetTagConstant(Tag),
Context.getNode(),
MDString::get(VMContext, Name),
CompileUnit.getNode(),
ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
- Type.getNode(),
+ Ty.getNode(),
};
return DIVariable(MDNode::get(VMContext, &Elts[0], 6));
}
@@ -962,14 +962,15 @@ DIVariable DIFactory::CreateComplexVariable(unsigned Tag, DIDescriptor Context,
const std::string &Name,
DICompileUnit CompileUnit,
unsigned LineNo,
- DIType Type, SmallVector<Value *, 9> &addr) {
+ DIType Ty,
+ SmallVector<Value *, 9> &addr) {
SmallVector<Value *, 9> Elts;
Elts.push_back(GetTagConstant(Tag));
Elts.push_back(Context.getNode());
Elts.push_back(MDString::get(VMContext, Name));
Elts.push_back(CompileUnit.getNode());
Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), LineNo));
- Elts.push_back(Type.getNode());
+ Elts.push_back(Ty.getNode());
Elts.insert(Elts.end(), addr.begin(), addr.end());
return DIVariable(MDNode::get(VMContext, &Elts[0], 6+addr.size()));
@@ -1035,8 +1036,8 @@ Instruction *DIFactory::InsertDeclare(Value *Storage, DIVariable D,
if (!DeclareFn)
DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare);
- Value *Elts[] = { Storage };
- Value *Args[] = { MDNode::get(Storage->getContext(), Elts, 1), D.getNode() };
+ Value *Args[] = { MDNode::get(Storage->getContext(), &Storage, 1),
+ D.getNode() };
return CallInst::Create(DeclareFn, Args, Args+2, "", InsertBefore);
}
@@ -1046,8 +1047,8 @@ Instruction *DIFactory::InsertDeclare(Value *Storage, DIVariable D,
if (!DeclareFn)
DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare);
- Value *Elts[] = { Storage };
- Value *Args[] = { MDNode::get(Storage->getContext(), Elts, 1), D.getNode() };
+ Value *Args[] = { MDNode::get(Storage->getContext(), &Storage, 1),
+ D.getNode() };
return CallInst::Create(DeclareFn, Args, Args+2, "", InsertAtEnd);
}
@@ -1059,8 +1060,7 @@ Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, uint64_t Offset,
if (!ValueFn)
ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value);
- Value *Elts[] = { V };
- Value *Args[] = { MDNode::get(V->getContext(), Elts, 1),
+ Value *Args[] = { MDNode::get(V->getContext(), &V, 1),
ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset),
D.getNode() };
return CallInst::Create(ValueFn, Args, Args+3, "", InsertBefore);
@@ -1074,8 +1074,7 @@ Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, uint64_t Offset,
if (!ValueFn)
ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value);
- Value *Elts[] = { V };
- Value *Args[] = { MDNode::get(V->getContext(), Elts, 1),
+ Value *Args[] = { MDNode::get(V->getContext(), &V, 1),
ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset),
D.getNode() };
return CallInst::Create(ValueFn, Args, Args+3, "", InsertAtEnd);
@@ -1139,9 +1138,9 @@ void DebugInfoFinder::processType(DIType DT) {
if (!DA.isNull())
for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) {
DIDescriptor D = DA.getElement(i);
- DIType TypeE = DIType(D.getNode());
- if (!TypeE.isNull())
- processType(TypeE);
+ DIType TyE = DIType(D.getNode());
+ if (!TyE.isNull())
+ processType(TyE);
else
processSubprogram(DISubprogram(D.getNode()));
}
@@ -1234,7 +1233,8 @@ bool DebugInfoFinder::addSubprogram(DISubprogram SP) {
return true;
}
-Value *llvm::findDbgGlobalDeclare(GlobalVariable *V) {
+/// Find the debug info descriptor corresponding to this global variable.
+static Value *findDbgGlobalDeclare(GlobalVariable *V) {
const Module *M = V->getParent();
NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.gv");
if (!NMD)
@@ -1252,7 +1252,7 @@ Value *llvm::findDbgGlobalDeclare(GlobalVariable *V) {
/// Finds the llvm.dbg.declare intrinsic corresponding to this value if any.
/// It looks through pointer casts too.
-const DbgDeclareInst *llvm::findDbgDeclare(const Value *V) {
+static const DbgDeclareInst *findDbgDeclare(const Value *V) {
V = V->stripPointerCasts();
if (!isa<Instruction>(V) && !isa<Argument>(V))
@@ -1320,23 +1320,15 @@ bool llvm::getLocationInfo(const Value *V, std::string &DisplayName,
/// from DILocation.
DebugLoc llvm::ExtractDebugLocation(DILocation &Loc,
DebugLocTracker &DebugLocInfo) {
- DebugLoc DL;
- MDNode *Context = Loc.getScope().getNode();
- MDNode *InlinedLoc = NULL;
- if (!Loc.getOrigLocation().isNull())
- InlinedLoc = Loc.getOrigLocation().getNode();
- // If this location is already tracked then use it.
- DebugLocTuple Tuple(Context, InlinedLoc, Loc.getLineNumber(),
- Loc.getColumnNumber());
- DenseMap<DebugLocTuple, unsigned>::iterator II
- = DebugLocInfo.DebugIdMap.find(Tuple);
+ DenseMap<MDNode *, unsigned>::iterator II
+ = DebugLocInfo.DebugIdMap.find(Loc.getNode());
if (II != DebugLocInfo.DebugIdMap.end())
return DebugLoc::get(II->second);
// Add a new location entry.
unsigned Id = DebugLocInfo.DebugLocations.size();
- DebugLocInfo.DebugLocations.push_back(Tuple);
- DebugLocInfo.DebugIdMap[Tuple] = Id;
+ DebugLocInfo.DebugLocations.push_back(Loc.getNode());
+ DebugLocInfo.DebugIdMap[Loc.getNode()] = Id;
return DebugLoc::get(Id);
}
diff --git a/lib/Analysis/DomPrinter.cpp b/lib/Analysis/DomPrinter.cpp
index 32b8994..3af687a 100644
--- a/lib/Analysis/DomPrinter.cpp
+++ b/lib/Analysis/DomPrinter.cpp
@@ -19,10 +19,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/DomPrinter.h"
-#include "llvm/Pass.h"
-#include "llvm/Function.h"
-#include "llvm/Analysis/CFGPrinter.h"
+
#include "llvm/Analysis/Dominators.h"
+#include "llvm/Analysis/DOTGraphTraitsPass.h"
#include "llvm/Analysis/PostDominators.h"
using namespace llvm;
@@ -110,29 +109,29 @@ struct GenericGraphViewer : public FunctionPass {
};
struct DomViewer
- : public GenericGraphViewer<DominatorTree, false> {
+ : public DOTGraphTraitsViewer<DominatorTree, false> {
static char ID;
- DomViewer() : GenericGraphViewer<DominatorTree, false>("dom", &ID){}
+ DomViewer() : DOTGraphTraitsViewer<DominatorTree, false>("dom", &ID){}
};
struct DomOnlyViewer
- : public GenericGraphViewer<DominatorTree, true> {
+ : public DOTGraphTraitsViewer<DominatorTree, true> {
static char ID;
- DomOnlyViewer() : GenericGraphViewer<DominatorTree, true>("domonly", &ID){}
+ DomOnlyViewer() : DOTGraphTraitsViewer<DominatorTree, true>("domonly", &ID){}
};
struct PostDomViewer
- : public GenericGraphViewer<PostDominatorTree, false> {
+ : public DOTGraphTraitsViewer<PostDominatorTree, false> {
static char ID;
PostDomViewer() :
- GenericGraphViewer<PostDominatorTree, false>("postdom", &ID){}
+ DOTGraphTraitsViewer<PostDominatorTree, false>("postdom", &ID){}
};
struct PostDomOnlyViewer
- : public GenericGraphViewer<PostDominatorTree, true> {
+ : public DOTGraphTraitsViewer<PostDominatorTree, true> {
static char ID;
PostDomOnlyViewer() :
- GenericGraphViewer<PostDominatorTree, true>("postdomonly", &ID){}
+ DOTGraphTraitsViewer<PostDominatorTree, true>("postdomonly", &ID){}
};
} // end anonymous namespace
@@ -155,67 +154,30 @@ RegisterPass<PostDomOnlyViewer> D("view-postdom-only",
"(with no function bodies)");
namespace {
-template <class Analysis, bool OnlyBBS>
-struct GenericGraphPrinter : public FunctionPass {
-
- std::string Name;
-
- GenericGraphPrinter(std::string GraphName, const void *ID)
- : FunctionPass(ID) {
- Name = GraphName;
- }
-
- virtual bool runOnFunction(Function &F) {
- Analysis *Graph;
- std::string Filename = Name + "." + F.getNameStr() + ".dot";
- errs() << "Writing '" << Filename << "'...";
-
- std::string ErrorInfo;
- raw_fd_ostream File(Filename.c_str(), ErrorInfo);
- Graph = &getAnalysis<Analysis>();
-
- std::string Title, GraphName;
- GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
- Title = GraphName + " for '" + F.getNameStr() + "' function";
-
- if (ErrorInfo.empty())
- WriteGraph(File, Graph, OnlyBBS, Name, Title);
- else
- errs() << " error opening file for writing!";
- errs() << "\n";
- return false;
- }
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AU.addRequired<Analysis>();
- }
-};
-
struct DomPrinter
- : public GenericGraphPrinter<DominatorTree, false> {
+ : public DOTGraphTraitsPrinter<DominatorTree, false> {
static char ID;
- DomPrinter() : GenericGraphPrinter<DominatorTree, false>("dom", &ID) {}
+ DomPrinter() : DOTGraphTraitsPrinter<DominatorTree, false>("dom", &ID) {}
};
struct DomOnlyPrinter
- : public GenericGraphPrinter<DominatorTree, true> {
+ : public DOTGraphTraitsPrinter<DominatorTree, true> {
static char ID;
- DomOnlyPrinter() : GenericGraphPrinter<DominatorTree, true>("domonly", &ID) {}
+ DomOnlyPrinter() : DOTGraphTraitsPrinter<DominatorTree, true>("domonly", &ID) {}
};
struct PostDomPrinter
- : public GenericGraphPrinter<PostDominatorTree, false> {
+ : public DOTGraphTraitsPrinter<PostDominatorTree, false> {
static char ID;
PostDomPrinter() :
- GenericGraphPrinter<PostDominatorTree, false>("postdom", &ID) {}
+ DOTGraphTraitsPrinter<PostDominatorTree, false>("postdom", &ID) {}
};
struct PostDomOnlyPrinter
- : public GenericGraphPrinter<PostDominatorTree, true> {
+ : public DOTGraphTraitsPrinter<PostDominatorTree, true> {
static char ID;
PostDomOnlyPrinter() :
- GenericGraphPrinter<PostDominatorTree, true>("postdomonly", &ID) {}
+ DOTGraphTraitsPrinter<PostDominatorTree, true>("postdomonly", &ID) {}
};
} // end anonymous namespace
diff --git a/lib/Analysis/IPA/Andersens.cpp b/lib/Analysis/IPA/Andersens.cpp
index 28c66af..4180206 100644
--- a/lib/Analysis/IPA/Andersens.cpp
+++ b/lib/Analysis/IPA/Andersens.cpp
@@ -475,6 +475,16 @@ namespace {
AU.setPreservesAll(); // Does not transform code
}
+ /// getAdjustedAnalysisPointer - This method is used when a pass implements
+ /// an analysis interface through multiple inheritance. If needed, it
+ /// should override this to adjust the this pointer as needed for the
+ /// specified pass info.
+ virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+ if (PI->isPassID(&AliasAnalysis::ID))
+ return (AliasAnalysis*)this;
+ return this;
+ }
+
//------------------------------------------------
// Implement the AliasAnalysis API
//
diff --git a/lib/Analysis/IPA/CallGraph.cpp b/lib/Analysis/IPA/CallGraph.cpp
index a826177..8c43aa1 100644
--- a/lib/Analysis/IPA/CallGraph.cpp
+++ b/lib/Analysis/IPA/CallGraph.cpp
@@ -26,7 +26,7 @@ namespace {
//===----------------------------------------------------------------------===//
// BasicCallGraph class definition
//
-class BasicCallGraph : public CallGraph, public ModulePass {
+class BasicCallGraph : public ModulePass, public CallGraph {
// Root is root of the call graph, or the external node if a 'main' function
// couldn't be found.
//
@@ -82,6 +82,16 @@ public:
destroy();
}
+ /// getAdjustedAnalysisPointer - This method is used when a pass implements
+ /// an analysis interface through multiple inheritance. If needed, it should
+ /// override this to adjust the this pointer as needed for the specified pass
+ /// info.
+ virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+ if (PI->isPassID(&CallGraph::ID))
+ return (CallGraph*)this;
+ return this;
+ }
+
CallGraphNode* getExternalCallingNode() const { return ExternalCallingNode; }
CallGraphNode* getCallsExternalNode() const { return CallsExternalNode; }
diff --git a/lib/Analysis/IPA/CallGraphSCCPass.cpp b/lib/Analysis/IPA/CallGraphSCCPass.cpp
index 5504b9b..0e333d1 100644
--- a/lib/Analysis/IPA/CallGraphSCCPass.cpp
+++ b/lib/Analysis/IPA/CallGraphSCCPass.cpp
@@ -57,6 +57,9 @@ public:
return "CallGraph Pass Manager";
}
+ virtual PMDataManager *getAsPMDataManager() { return this; }
+ virtual Pass *getAsPass() { return this; }
+
// Print passes managed by this manager
void dumpPassStructure(unsigned Offset) {
errs().indent(Offset*2) << "Call Graph SCC Pass Manager\n";
@@ -90,7 +93,10 @@ char CGPassManager::ID = 0;
bool CGPassManager::RunPassOnSCC(Pass *P, std::vector<CallGraphNode*> &CurSCC,
CallGraph &CG, bool &CallGraphUpToDate) {
bool Changed = false;
- if (CallGraphSCCPass *CGSP = dynamic_cast<CallGraphSCCPass*>(P)) {
+ PMDataManager *PM = P->getAsPMDataManager();
+
+ if (PM == 0) {
+ CallGraphSCCPass *CGSP = (CallGraphSCCPass*)P;
if (!CallGraphUpToDate) {
RefreshCallGraph(CurSCC, CG, false);
CallGraphUpToDate = true;
@@ -110,8 +116,10 @@ bool CGPassManager::RunPassOnSCC(Pass *P, std::vector<CallGraphNode*> &CurSCC,
return Changed;
}
- FPPassManager *FPP = dynamic_cast<FPPassManager *>(P);
- assert(FPP && "Invalid CGPassManager member");
+
+ assert(PM->getPassManagerType() == PMT_FunctionPassManager &&
+ "Invalid CGPassManager member");
+ FPPassManager *FPP = (FPPassManager*)P;
// Run pass P on all functions in the current SCC.
for (unsigned i = 0, e = CurSCC.size(); i != e; ++i) {
@@ -360,14 +368,13 @@ bool CGPassManager::runOnModule(Module &M) {
/// Initialize CG
bool CGPassManager::doInitialization(CallGraph &CG) {
bool Changed = false;
- for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
- Pass *P = getContainedPass(Index);
- if (CallGraphSCCPass *CGSP = dynamic_cast<CallGraphSCCPass *>(P)) {
- Changed |= CGSP->doInitialization(CG);
+ for (unsigned i = 0, e = getNumContainedPasses(); i != e; ++i) {
+ if (PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) {
+ assert(PM->getPassManagerType() == PMT_FunctionPassManager &&
+ "Invalid CGPassManager member");
+ Changed |= ((FPPassManager*)PM)->doInitialization(CG.getModule());
} else {
- FPPassManager *FP = dynamic_cast<FPPassManager *>(P);
- assert (FP && "Invalid CGPassManager member");
- Changed |= FP->doInitialization(CG.getModule());
+ Changed |= ((CallGraphSCCPass*)getContainedPass(i))->doInitialization(CG);
}
}
return Changed;
@@ -376,14 +383,13 @@ bool CGPassManager::doInitialization(CallGraph &CG) {
/// Finalize CG
bool CGPassManager::doFinalization(CallGraph &CG) {
bool Changed = false;
- for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
- Pass *P = getContainedPass(Index);
- if (CallGraphSCCPass *CGSP = dynamic_cast<CallGraphSCCPass *>(P)) {
- Changed |= CGSP->doFinalization(CG);
+ for (unsigned i = 0, e = getNumContainedPasses(); i != e; ++i) {
+ if (PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) {
+ assert(PM->getPassManagerType() == PMT_FunctionPassManager &&
+ "Invalid CGPassManager member");
+ Changed |= ((FPPassManager*)PM)->doFinalization(CG.getModule());
} else {
- FPPassManager *FP = dynamic_cast<FPPassManager *>(P);
- assert (FP && "Invalid CGPassManager member");
- Changed |= FP->doFinalization(CG.getModule());
+ Changed |= ((CallGraphSCCPass*)getContainedPass(i))->doFinalization(CG);
}
}
return Changed;
@@ -397,13 +403,14 @@ void CallGraphSCCPass::assignPassManager(PMStack &PMS,
PMS.top()->getPassManagerType() > PMT_CallGraphPassManager)
PMS.pop();
- assert (!PMS.empty() && "Unable to handle Call Graph Pass");
- CGPassManager *CGP = dynamic_cast<CGPassManager *>(PMS.top());
-
- // Create new Call Graph SCC Pass Manager if it does not exist.
- if (!CGP) {
-
- assert (!PMS.empty() && "Unable to create Call Graph Pass Manager");
+ assert(!PMS.empty() && "Unable to handle Call Graph Pass");
+ CGPassManager *CGP;
+
+ if (PMS.top()->getPassManagerType() == PMT_CallGraphPassManager)
+ CGP = (CGPassManager*)PMS.top();
+ else {
+ // Create new Call Graph SCC Pass Manager if it does not exist.
+ assert(!PMS.empty() && "Unable to create Call Graph Pass Manager");
PMDataManager *PMD = PMS.top();
// [1] Create new Call Graph Pass Manager
@@ -415,7 +422,7 @@ void CallGraphSCCPass::assignPassManager(PMStack &PMS,
// [3] Assign manager to manage this new manager. This may create
// and push new managers into PMS
- Pass *P = dynamic_cast<Pass *>(CGP);
+ Pass *P = CGP;
TPM->schedulePass(P);
// [4] Push new manager into PMS
diff --git a/lib/Analysis/IPA/GlobalsModRef.cpp b/lib/Analysis/IPA/GlobalsModRef.cpp
index a979a99..e803a48 100644
--- a/lib/Analysis/IPA/GlobalsModRef.cpp
+++ b/lib/Analysis/IPA/GlobalsModRef.cpp
@@ -145,6 +145,16 @@ namespace {
virtual void deleteValue(Value *V);
virtual void copyValue(Value *From, Value *To);
+ /// getAdjustedAnalysisPointer - This method is used when a pass implements
+ /// an analysis interface through multiple inheritance. If needed, it
+ /// should override this to adjust the this pointer as needed for the
+ /// specified pass info.
+ virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+ if (PI->isPassID(&AliasAnalysis::ID))
+ return (AliasAnalysis*)this;
+ return this;
+ }
+
private:
/// getFunctionInfo - Return the function info for the function, or null if
/// we don't have anything useful to say about it.
diff --git a/lib/Analysis/IPA/Makefile b/lib/Analysis/IPA/Makefile
index adacb16..da719ba 100644
--- a/lib/Analysis/IPA/Makefile
+++ b/lib/Analysis/IPA/Makefile
@@ -10,5 +10,7 @@
LEVEL = ../../..
LIBRARYNAME = LLVMipa
BUILD_ARCHIVE = 1
+CXXFLAGS = -fno-rtti
+
include $(LEVEL)/Makefile.common
diff --git a/lib/Analysis/IVUsers.cpp b/lib/Analysis/IVUsers.cpp
index 26c0c9e..38611cc 100644
--- a/lib/Analysis/IVUsers.cpp
+++ b/lib/Analysis/IVUsers.cpp
@@ -324,12 +324,19 @@ const SCEV *IVUsers::getReplacementExpr(const IVStrideUse &U) const {
// the actual replacement value.
if (U.isUseOfPostIncrementedValue())
RetVal = SE->getAddExpr(RetVal, U.getParent()->Stride);
- // Evaluate the expression out of the loop, if possible.
- if (!L->contains(U.getUser())) {
- const SCEV *ExitVal = SE->getSCEVAtScope(RetVal, L->getParentLoop());
- if (ExitVal->isLoopInvariant(L))
- RetVal = ExitVal;
- }
+ return RetVal;
+}
+
+/// getCanonicalExpr - Return a SCEV expression which computes the
+/// value of the SCEV of the given IVStrideUse, ignoring the
+/// isUseOfPostIncrementedValue flag.
+const SCEV *IVUsers::getCanonicalExpr(const IVStrideUse &U) const {
+ // Start with zero.
+ const SCEV *RetVal = SE->getIntegerSCEV(0, U.getParent()->Stride->getType());
+ // Create the basic add recurrence.
+ RetVal = SE->getAddRecExpr(RetVal, U.getParent()->Stride, L);
+ // Add the offset in a separate step, because it may be loop-variant.
+ RetVal = SE->getAddExpr(RetVal, U.getOffset());
return RetVal;
}
diff --git a/lib/Analysis/LoopPass.cpp b/lib/Analysis/LoopPass.cpp
index 43463cd..2d613f6 100644
--- a/lib/Analysis/LoopPass.cpp
+++ b/lib/Analysis/LoopPass.cpp
@@ -147,8 +147,7 @@ void LPPassManager::redoLoop(Loop *L) {
void LPPassManager::cloneBasicBlockSimpleAnalysis(BasicBlock *From,
BasicBlock *To, Loop *L) {
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
- Pass *P = getContainedPass(Index);
- LoopPass *LP = dynamic_cast<LoopPass *>(P);
+ LoopPass *LP = (LoopPass *)getContainedPass(Index);
LP->cloneBasicBlockAnalysis(From, To, L);
}
}
@@ -163,8 +162,7 @@ void LPPassManager::deleteSimpleAnalysisValue(Value *V, Loop *L) {
}
}
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
- Pass *P = getContainedPass(Index);
- LoopPass *LP = dynamic_cast<LoopPass *>(P);
+ LoopPass *LP = (LoopPass *)getContainedPass(Index);
LP->deleteAnalysisValue(V, L);
}
}
@@ -206,10 +204,8 @@ bool LPPassManager::runOnFunction(Function &F) {
I != E; ++I) {
Loop *L = *I;
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
- Pass *P = getContainedPass(Index);
- LoopPass *LP = dynamic_cast<LoopPass *>(P);
- if (LP)
- Changed |= LP->doInitialization(L, *this);
+ LoopPass *P = (LoopPass*)getContainedPass(Index);
+ Changed |= P->doInitialization(L, *this);
}
}
@@ -222,7 +218,7 @@ bool LPPassManager::runOnFunction(Function &F) {
// Run all passes on the current Loop.
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
- Pass *P = getContainedPass(Index);
+ LoopPass *P = (LoopPass*)getContainedPass(Index);
dumpPassInfo(P, EXECUTION_MSG, ON_LOOP_MSG,
CurrentLoop->getHeader()->getNameStr());
@@ -230,12 +226,10 @@ bool LPPassManager::runOnFunction(Function &F) {
initializeAnalysisImpl(P);
- LoopPass *LP = dynamic_cast<LoopPass *>(P);
- assert(LP && "Invalid LPPassManager member");
{
- PassManagerPrettyStackEntry X(LP, *CurrentLoop->getHeader());
+ PassManagerPrettyStackEntry X(P, *CurrentLoop->getHeader());
Timer *T = StartPassTimer(P);
- Changed |= LP->runOnLoop(CurrentLoop, *this);
+ Changed |= P->runOnLoop(CurrentLoop, *this);
StopPassTimer(P, T);
}
@@ -256,7 +250,7 @@ bool LPPassManager::runOnFunction(Function &F) {
StopPassTimer(LI, T);
// Then call the regular verifyAnalysis functions.
- verifyPreservedAnalysis(LP);
+ verifyPreservedAnalysis(P);
}
removeNotPreservedAnalysis(P);
@@ -289,10 +283,8 @@ bool LPPassManager::runOnFunction(Function &F) {
// Finalization
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
- Pass *P = getContainedPass(Index);
- LoopPass *LP = dynamic_cast <LoopPass *>(P);
- if (LP)
- Changed |= LP->doFinalization();
+ LoopPass *P = (LoopPass *)getContainedPass(Index);
+ Changed |= P->doFinalization();
}
return Changed;
@@ -325,12 +317,11 @@ void LoopPass::preparePassManager(PMStack &PMS) {
PMS.top()->getPassManagerType() > PMT_LoopPassManager)
PMS.pop();
- LPPassManager *LPPM = dynamic_cast<LPPassManager *>(PMS.top());
-
// If this pass is destroying high level information that is used
// by other passes that are managed by LPM then do not insert
// this pass in current LPM. Use new LPPassManager.
- if (LPPM && !LPPM->preserveHigherLevelAnalysis(this))
+ if (PMS.top()->getPassManagerType() == PMT_LoopPassManager &&
+ !PMS.top()->preserveHigherLevelAnalysis(this))
PMS.pop();
}
@@ -342,11 +333,11 @@ void LoopPass::assignPassManager(PMStack &PMS,
PMS.top()->getPassManagerType() > PMT_LoopPassManager)
PMS.pop();
- LPPassManager *LPPM = dynamic_cast<LPPassManager *>(PMS.top());
-
- // Create new Loop Pass Manager if it does not exist.
- if (!LPPM) {
-
+ LPPassManager *LPPM;
+ if (PMS.top()->getPassManagerType() == PMT_LoopPassManager)
+ LPPM = (LPPassManager*)PMS.top();
+ else {
+ // Create new Loop Pass Manager if it does not exist.
assert (!PMS.empty() && "Unable to create Loop Pass Manager");
PMDataManager *PMD = PMS.top();
@@ -360,7 +351,7 @@ void LoopPass::assignPassManager(PMStack &PMS,
// [3] Assign manager to manage this new manager. This may create
// and push new managers into PMS
- Pass *P = dynamic_cast<Pass *>(LPPM);
+ Pass *P = LPPM->getAsPass();
TPM->schedulePass(P);
// [4] Push new manager into PMS
diff --git a/lib/Analysis/Makefile b/lib/Analysis/Makefile
index 4af6d35..f61b8aa 100644
--- a/lib/Analysis/Makefile
+++ b/lib/Analysis/Makefile
@@ -11,6 +11,7 @@ LEVEL = ../..
LIBRARYNAME = LLVMAnalysis
DIRS = IPA
BUILD_ARCHIVE = 1
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Analysis/ProfileEstimatorPass.cpp b/lib/Analysis/ProfileEstimatorPass.cpp
index cf9311a..bce6b31 100644
--- a/lib/Analysis/ProfileEstimatorPass.cpp
+++ b/lib/Analysis/ProfileEstimatorPass.cpp
@@ -55,6 +55,16 @@ namespace {
/// run - Estimate the profile information from the specified file.
virtual bool runOnFunction(Function &F);
+ /// getAdjustedAnalysisPointer - This method is used when a pass implements
+ /// an analysis interface through multiple inheritance. If needed, it
+ /// should override this to adjust the this pointer as needed for the
+ /// specified pass info.
+ virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+ if (PI->isPassID(&ProfileInfo::ID))
+ return (ProfileInfo*)this;
+ return this;
+ }
+
virtual void recurseBasicBlock(BasicBlock *BB);
void inline printEdgeWeight(Edge);
diff --git a/lib/Analysis/ProfileInfo.cpp b/lib/Analysis/ProfileInfo.cpp
index afd86b1..85531be 100644
--- a/lib/Analysis/ProfileInfo.cpp
+++ b/lib/Analysis/ProfileInfo.cpp
@@ -1079,6 +1079,20 @@ namespace {
struct NoProfileInfo : public ImmutablePass, public ProfileInfo {
static char ID; // Class identification, replacement for typeinfo
NoProfileInfo() : ImmutablePass(&ID) {}
+
+ /// getAdjustedAnalysisPointer - This method is used when a pass implements
+ /// an analysis interface through multiple inheritance. If needed, it
+ /// should override this to adjust the this pointer as needed for the
+ /// specified pass info.
+ virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+ if (PI->isPassID(&ProfileInfo::ID))
+ return (ProfileInfo*)this;
+ return this;
+ }
+
+ virtual const char *getPassName() const {
+ return "NoProfileInfo";
+ }
};
} // End of anonymous namespace
diff --git a/lib/Analysis/ProfileInfoLoaderPass.cpp b/lib/Analysis/ProfileInfoLoaderPass.cpp
index d8c511f..ac9ed52 100644
--- a/lib/Analysis/ProfileInfoLoaderPass.cpp
+++ b/lib/Analysis/ProfileInfoLoaderPass.cpp
@@ -63,6 +63,16 @@ namespace {
virtual void readEdgeOrRemember(Edge, Edge&, unsigned &, double &);
virtual void readEdge(ProfileInfo::Edge, std::vector<unsigned>&);
+ /// getAdjustedAnalysisPointer - This method is used when a pass implements
+ /// an analysis interface through multiple inheritance. If needed, it
+ /// should override this to adjust the this pointer as needed for the
+ /// specified pass info.
+ virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+ if (PI->isPassID(&ProfileInfo::ID))
+ return (ProfileInfo*)this;
+ return this;
+ }
+
/// run - Load the profile information from the specified file.
virtual bool runOnModule(Module &M);
};
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index 4d85ce4..2f44913 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -1089,6 +1089,15 @@ const SCEV *ScalarEvolution::getAnyExtendExpr(const SCEV *Op,
if (!isa<SCEVSignExtendExpr>(SExt))
return SExt;
+ // Force the cast to be folded into the operands of an addrec.
+ if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Op)) {
+ SmallVector<const SCEV *, 4> Ops;
+ for (SCEVAddRecExpr::op_iterator I = AR->op_begin(), E = AR->op_end();
+ I != E; ++I)
+ Ops.push_back(getAnyExtendExpr(*I, Ty));
+ return getAddRecExpr(Ops, AR->getLoop());
+ }
+
// If the expression is obviously signed, use the sext cast value.
if (isa<SCEVSMaxExpr>(Op))
return SExt;
@@ -1204,6 +1213,17 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
"SCEVAddExpr operand types don't match!");
#endif
+ // If HasNSW is true and all the operands are non-negative, infer HasNUW.
+ if (!HasNUW && HasNSW) {
+ bool All = true;
+ for (unsigned i = 0, e = Ops.size(); i != e; ++i)
+ if (!isKnownNonNegative(Ops[i])) {
+ All = false;
+ break;
+ }
+ if (All) HasNUW = true;
+ }
+
// Sort by complexity, this groups all similar expression types together.
GroupByComplexity(Ops, LI);
@@ -1521,21 +1541,24 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
ID.AddPointer(Ops[i]);
void *IP = 0;
- if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
- SCEVAddExpr *S = SCEVAllocator.Allocate<SCEVAddExpr>();
- new (S) SCEVAddExpr(ID, Ops);
- UniqueSCEVs.InsertNode(S, IP);
+ SCEVAddExpr *S =
+ static_cast<SCEVAddExpr *>(UniqueSCEVs.FindNodeOrInsertPos(ID, IP));
+ if (!S) {
+ S = SCEVAllocator.Allocate<SCEVAddExpr>();
+ new (S) SCEVAddExpr(ID, Ops);
+ UniqueSCEVs.InsertNode(S, IP);
+ }
if (HasNUW) S->setHasNoUnsignedWrap(true);
if (HasNSW) S->setHasNoSignedWrap(true);
return S;
}
-
/// getMulExpr - Get a canonical multiply expression, or something simpler if
/// possible.
const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
bool HasNUW, bool HasNSW) {
assert(!Ops.empty() && "Cannot get empty mul!");
+ if (Ops.size() == 1) return Ops[0];
#ifndef NDEBUG
for (unsigned i = 1, e = Ops.size(); i != e; ++i)
assert(getEffectiveSCEVType(Ops[i]->getType()) ==
@@ -1543,6 +1566,17 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
"SCEVMulExpr operand types don't match!");
#endif
+ // If HasNSW is true and all the operands are non-negative, infer HasNUW.
+ if (!HasNUW && HasNSW) {
+ bool All = true;
+ for (unsigned i = 0, e = Ops.size(); i != e; ++i)
+ if (!isKnownNonNegative(Ops[i])) {
+ All = false;
+ break;
+ }
+ if (All) HasNUW = true;
+ }
+
// Sort by complexity, this groups all similar expression types together.
GroupByComplexity(Ops, LI);
@@ -1558,7 +1592,6 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
return getAddExpr(getMulExpr(LHSC, Add->getOperand(0)),
getMulExpr(LHSC, Add->getOperand(1)));
-
++Idx;
while (const SCEVConstant *RHSC = dyn_cast<SCEVConstant>(Ops[Idx])) {
// We found two constants, fold them together!
@@ -1578,6 +1611,22 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
} else if (cast<SCEVConstant>(Ops[0])->getValue()->isZero()) {
// If we have a multiply of zero, it will always be zero.
return Ops[0];
+ } else if (Ops[0]->isAllOnesValue()) {
+ // If we have a mul by -1 of an add, try distributing the -1 among the
+ // add operands.
+ if (Ops.size() == 2)
+ if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(Ops[1])) {
+ SmallVector<const SCEV *, 4> NewOps;
+ bool AnyFolded = false;
+ for (SCEVAddRecExpr::op_iterator I = Add->op_begin(), E = Add->op_end();
+ I != E; ++I) {
+ const SCEV *Mul = getMulExpr(Ops[0], *I);
+ if (!isa<SCEVMulExpr>(Mul)) AnyFolded = true;
+ NewOps.push_back(Mul);
+ }
+ if (AnyFolded)
+ return getAddExpr(NewOps);
+ }
}
}
@@ -1644,7 +1693,9 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
// It's tempting to propagate the NSW flag here, but nsw multiplication
// is not associative so this isn't necessarily safe.
- const SCEV *NewRec = getAddRecExpr(NewOps, AddRec->getLoop());
+ const SCEV *NewRec = getAddRecExpr(NewOps, AddRec->getLoop(),
+ HasNUW && AddRec->hasNoUnsignedWrap(),
+ /*HasNSW=*/false);
// If all of the other operands were loop invariant, we are done.
if (Ops.size() == 1) return NewRec;
@@ -1698,10 +1749,13 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
ID.AddPointer(Ops[i]);
void *IP = 0;
- if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
- SCEVMulExpr *S = SCEVAllocator.Allocate<SCEVMulExpr>();
- new (S) SCEVMulExpr(ID, Ops);
- UniqueSCEVs.InsertNode(S, IP);
+ SCEVMulExpr *S =
+ static_cast<SCEVMulExpr *>(UniqueSCEVs.FindNodeOrInsertPos(ID, IP));
+ if (!S) {
+ S = SCEVAllocator.Allocate<SCEVMulExpr>();
+ new (S) SCEVMulExpr(ID, Ops);
+ UniqueSCEVs.InsertNode(S, IP);
+ }
if (HasNUW) S->setHasNoUnsignedWrap(true);
if (HasNSW) S->setHasNoSignedWrap(true);
return S;
@@ -1844,10 +1898,24 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
return getAddRecExpr(Operands, L, HasNUW, HasNSW); // {X,+,0} --> X
}
+ // If HasNSW is true and all the operands are non-negative, infer HasNUW.
+ if (!HasNUW && HasNSW) {
+ bool All = true;
+ for (unsigned i = 0, e = Operands.size(); i != e; ++i)
+ if (!isKnownNonNegative(Operands[i])) {
+ All = false;
+ break;
+ }
+ if (All) HasNUW = true;
+ }
+
// Canonicalize nested AddRecs in by nesting them in order of loop depth.
if (const SCEVAddRecExpr *NestedAR = dyn_cast<SCEVAddRecExpr>(Operands[0])) {
const Loop *NestedLoop = NestedAR->getLoop();
- if (L->getLoopDepth() < NestedLoop->getLoopDepth()) {
+ if (L->contains(NestedLoop->getHeader()) ?
+ (L->getLoopDepth() < NestedLoop->getLoopDepth()) :
+ (!NestedLoop->contains(L->getHeader()) &&
+ DT->dominates(L->getHeader(), NestedLoop->getHeader()))) {
SmallVector<const SCEV *, 4> NestedOperands(NestedAR->op_begin(),
NestedAR->op_end());
Operands[0] = NestedAR->getStart();
@@ -1877,6 +1945,8 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
}
}
+ // Okay, it looks like we really DO need an addrec expr. Check to see if we
+ // already have one, otherwise create a new one.
FoldingSetNodeID ID;
ID.AddInteger(scAddRecExpr);
ID.AddInteger(Operands.size());
@@ -1884,10 +1954,13 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
ID.AddPointer(Operands[i]);
ID.AddPointer(L);
void *IP = 0;
- if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
- SCEVAddRecExpr *S = SCEVAllocator.Allocate<SCEVAddRecExpr>();
- new (S) SCEVAddRecExpr(ID, Operands, L);
- UniqueSCEVs.InsertNode(S, IP);
+ SCEVAddRecExpr *S =
+ static_cast<SCEVAddRecExpr *>(UniqueSCEVs.FindNodeOrInsertPos(ID, IP));
+ if (!S) {
+ S = SCEVAllocator.Allocate<SCEVAddRecExpr>();
+ new (S) SCEVAddRecExpr(ID, Operands, L);
+ UniqueSCEVs.InsertNode(S, IP);
+ }
if (HasNUW) S->setHasNoUnsignedWrap(true);
if (HasNSW) S->setHasNoSignedWrap(true);
return S;
@@ -2525,31 +2598,28 @@ const SCEV *ScalarEvolution::createNodeForPHI(PHINode *PN) {
if (Accum->isLoopInvariant(L) ||
(isa<SCEVAddRecExpr>(Accum) &&
cast<SCEVAddRecExpr>(Accum)->getLoop() == L)) {
+ bool HasNUW = false;
+ bool HasNSW = false;
+
+ // If the increment doesn't overflow, then neither the addrec nor
+ // the post-increment will overflow.
+ if (const AddOperator *OBO = dyn_cast<AddOperator>(BEValueV)) {
+ if (OBO->hasNoUnsignedWrap())
+ HasNUW = true;
+ if (OBO->hasNoSignedWrap())
+ HasNSW = true;
+ }
+
const SCEV *StartVal =
getSCEV(PN->getIncomingValue(IncomingEdge));
- const SCEVAddRecExpr *PHISCEV =
- cast<SCEVAddRecExpr>(getAddRecExpr(StartVal, Accum, L));
-
- // If the increment doesn't overflow, then neither the addrec nor the
- // post-increment will overflow.
- if (const AddOperator *OBO = dyn_cast<AddOperator>(BEValueV))
- if (OBO->getOperand(0) == PN &&
- getSCEV(OBO->getOperand(1)) ==
- PHISCEV->getStepRecurrence(*this)) {
- const SCEVAddRecExpr *PostInc = PHISCEV->getPostIncExpr(*this);
- if (OBO->hasNoUnsignedWrap()) {
- const_cast<SCEVAddRecExpr *>(PHISCEV)
- ->setHasNoUnsignedWrap(true);
- const_cast<SCEVAddRecExpr *>(PostInc)
- ->setHasNoUnsignedWrap(true);
- }
- if (OBO->hasNoSignedWrap()) {
- const_cast<SCEVAddRecExpr *>(PHISCEV)
- ->setHasNoSignedWrap(true);
- const_cast<SCEVAddRecExpr *>(PostInc)
- ->setHasNoSignedWrap(true);
- }
- }
+ const SCEV *PHISCEV =
+ getAddRecExpr(StartVal, Accum, L, HasNUW, HasNSW);
+
+ // Since the no-wrap flags are on the increment, they apply to the
+ // post-incremented value as well.
+ if (Accum->isLoopInvariant(L))
+ (void)getAddRecExpr(getAddExpr(StartVal, Accum),
+ Accum, L, HasNUW, HasNSW);
// Okay, for the entire analysis of this edge we assumed the PHI
// to be symbolic. We now need to go back and purge all of the
@@ -2781,26 +2851,29 @@ ScalarEvolution::getUnsignedRange(const SCEV *S) {
if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S)) {
const SCEV *T = getBackedgeTakenCount(AddRec->getLoop());
const SCEVConstant *Trip = dyn_cast<SCEVConstant>(T);
- if (!Trip) return FullSet;
+ ConstantRange ConservativeResult = FullSet;
+
+ // If there's no unsigned wrap, the value will never be less than its
+ // initial value.
+ if (AddRec->hasNoUnsignedWrap())
+ if (const SCEVConstant *C = dyn_cast<SCEVConstant>(AddRec->getStart()))
+ ConservativeResult =
+ ConstantRange(C->getValue()->getValue(),
+ APInt(getTypeSizeInBits(C->getType()), 0));
// TODO: non-affine addrec
- if (AddRec->isAffine()) {
+ if (Trip && AddRec->isAffine()) {
const Type *Ty = AddRec->getType();
const SCEV *MaxBECount = getMaxBackedgeTakenCount(AddRec->getLoop());
if (getTypeSizeInBits(MaxBECount->getType()) <= getTypeSizeInBits(Ty)) {
MaxBECount = getNoopOrZeroExtend(MaxBECount, Ty);
const SCEV *Start = AddRec->getStart();
- const SCEV *Step = AddRec->getStepRecurrence(*this);
const SCEV *End = AddRec->evaluateAtIteration(MaxBECount, *this);
// Check for overflow.
- // TODO: This is very conservative.
- if (!(Step->isOne() &&
- isKnownPredicate(ICmpInst::ICMP_ULT, Start, End)) &&
- !(Step->isAllOnesValue() &&
- isKnownPredicate(ICmpInst::ICMP_UGT, Start, End)))
- return FullSet;
+ if (!AddRec->hasNoUnsignedWrap())
+ return ConservativeResult;
ConstantRange StartRange = getUnsignedRange(Start);
ConstantRange EndRange = getUnsignedRange(End);
@@ -2809,10 +2882,12 @@ ScalarEvolution::getUnsignedRange(const SCEV *S) {
APInt Max = APIntOps::umax(StartRange.getUnsignedMax(),
EndRange.getUnsignedMax());
if (Min.isMinValue() && Max.isMaxValue())
- return FullSet;
+ return ConservativeResult;
return ConstantRange(Min, Max+1);
}
}
+
+ return ConservativeResult;
}
if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {
@@ -2891,26 +2966,39 @@ ScalarEvolution::getSignedRange(const SCEV *S) {
if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S)) {
const SCEV *T = getBackedgeTakenCount(AddRec->getLoop());
const SCEVConstant *Trip = dyn_cast<SCEVConstant>(T);
- if (!Trip) return FullSet;
+ ConstantRange ConservativeResult = FullSet;
+
+ // If there's no signed wrap, and all the operands have the same sign or
+ // zero, the value won't ever change sign.
+ if (AddRec->hasNoSignedWrap()) {
+ bool AllNonNeg = true;
+ bool AllNonPos = true;
+ for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i) {
+ if (!isKnownNonNegative(AddRec->getOperand(i))) AllNonNeg = false;
+ if (!isKnownNonPositive(AddRec->getOperand(i))) AllNonPos = false;
+ }
+ unsigned BitWidth = getTypeSizeInBits(AddRec->getType());
+ if (AllNonNeg)
+ ConservativeResult = ConstantRange(APInt(BitWidth, 0),
+ APInt::getSignedMinValue(BitWidth));
+ else if (AllNonPos)
+ ConservativeResult = ConstantRange(APInt::getSignedMinValue(BitWidth),
+ APInt(BitWidth, 1));
+ }
// TODO: non-affine addrec
- if (AddRec->isAffine()) {
+ if (Trip && AddRec->isAffine()) {
const Type *Ty = AddRec->getType();
const SCEV *MaxBECount = getMaxBackedgeTakenCount(AddRec->getLoop());
if (getTypeSizeInBits(MaxBECount->getType()) <= getTypeSizeInBits(Ty)) {
MaxBECount = getNoopOrZeroExtend(MaxBECount, Ty);
const SCEV *Start = AddRec->getStart();
- const SCEV *Step = AddRec->getStepRecurrence(*this);
const SCEV *End = AddRec->evaluateAtIteration(MaxBECount, *this);
// Check for overflow.
- // TODO: This is very conservative.
- if (!(Step->isOne() &&
- isKnownPredicate(ICmpInst::ICMP_SLT, Start, End)) &&
- !(Step->isAllOnesValue() &&
- isKnownPredicate(ICmpInst::ICMP_SGT, Start, End)))
- return FullSet;
+ if (!AddRec->hasNoSignedWrap())
+ return ConservativeResult;
ConstantRange StartRange = getSignedRange(Start);
ConstantRange EndRange = getSignedRange(End);
@@ -2919,15 +3007,19 @@ ScalarEvolution::getSignedRange(const SCEV *S) {
APInt Max = APIntOps::smax(StartRange.getSignedMax(),
EndRange.getSignedMax());
if (Min.isMinSignedValue() && Max.isMaxSignedValue())
- return FullSet;
+ return ConservativeResult;
return ConstantRange(Min, Max+1);
}
}
+
+ return ConservativeResult;
}
if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {
// For a SCEVUnknown, ask ValueTracking.
unsigned BitWidth = getTypeSizeInBits(U->getType());
+ if (!U->getValue()->getType()->isInteger() && !TD)
+ return FullSet;
unsigned NS = ComputeNumSignBits(U->getValue(), TD);
if (NS == 1)
return FullSet;
@@ -5167,6 +5259,7 @@ ScalarEvolution::ScalarEvolution()
bool ScalarEvolution::runOnFunction(Function &F) {
this->F = &F;
LI = &getAnalysis<LoopInfo>();
+ DT = &getAnalysis<DominatorTree>();
TD = getAnalysisIfAvailable<TargetData>();
return false;
}
@@ -5183,6 +5276,7 @@ void ScalarEvolution::releaseMemory() {
void ScalarEvolution::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequiredTransitive<LoopInfo>();
+ AU.addRequiredTransitive<DominatorTree>();
}
bool ScalarEvolution::hasLoopInvariantBackedgeTakenCount(const Loop *L) {
diff --git a/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp b/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp
index ef0e97b..498c4a8 100644
--- a/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp
+++ b/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp
@@ -32,6 +32,16 @@ namespace {
static char ID; // Class identification, replacement for typeinfo
ScalarEvolutionAliasAnalysis() : FunctionPass(&ID), SE(0) {}
+ /// getAdjustedAnalysisPointer - This method is used when a pass implements
+ /// an analysis interface through multiple inheritance. If needed, it
+ /// should override this to adjust the this pointer as needed for the
+ /// specified pass info.
+ virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) {
+ if (PI->isPassID(&AliasAnalysis::ID))
+ return (AliasAnalysis*)this;
+ return this;
+ }
+
private:
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual bool runOnFunction(Function &F);
diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp
index 7157d47..a72f58f 100644
--- a/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -81,7 +81,7 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, const Type *Ty) {
Instruction *I = CastInst::Create(Op, V, Ty, V->getName(),
A->getParent()->getEntryBlock().begin());
- InsertedValues.insert(I);
+ rememberInstruction(I);
return I;
}
@@ -98,14 +98,16 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, const Type *Ty) {
It = cast<InvokeInst>(I)->getNormalDest()->begin();
while (isa<PHINode>(It)) ++It;
if (It != BasicBlock::iterator(CI)) {
- // Recreate the cast at the beginning of the entry block.
+ // Recreate the cast after the user.
// The old cast is left in place in case it is being used
// as an insert point.
Instruction *NewCI = CastInst::Create(Op, V, Ty, "", It);
NewCI->takeName(CI);
CI->replaceAllUsesWith(NewCI);
+ rememberInstruction(NewCI);
return NewCI;
}
+ rememberInstruction(CI);
return CI;
}
}
@@ -114,7 +116,7 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, const Type *Ty) {
IP = II->getNormalDest()->begin();
while (isa<PHINode>(IP)) ++IP;
Instruction *CI = CastInst::Create(Op, V, Ty, V->getName(), IP);
- InsertedValues.insert(CI);
+ rememberInstruction(CI);
return CI;
}
@@ -144,7 +146,7 @@ Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode,
// If we haven't found this binop, insert it.
Value *BO = Builder.CreateBinOp(Opcode, LHS, RHS, "tmp");
- InsertedValues.insert(BO);
+ rememberInstruction(BO);
return BO;
}
@@ -323,7 +325,7 @@ static void SplitAddRecs(SmallVectorImpl<const SCEV *> &Ops,
/// http://llvm.org/docs/LangRef.html#pointeraliasing
/// for details.
///
-/// Design note: The correctness of using getelmeentptr here depends on
+/// Design note: The correctness of using getelementptr here depends on
/// ScalarEvolution not recognizing inttoptr and ptrtoint operators, as
/// they may introduce pointer arithmetic which may not be safely converted
/// into getelementptr.
@@ -491,22 +493,39 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
// Emit a GEP.
Value *GEP = Builder.CreateGEP(V, Idx, "uglygep");
- InsertedValues.insert(GEP);
+ rememberInstruction(GEP);
return GEP;
}
// Insert a pretty getelementptr. Note that this GEP is not marked inbounds,
// because ScalarEvolution may have changed the address arithmetic to
// compute a value which is beyond the end of the allocated object.
- Value *GEP = Builder.CreateGEP(V,
+ Value *Casted = V;
+ if (V->getType() != PTy)
+ Casted = InsertNoopCastOfTo(Casted, PTy);
+ Value *GEP = Builder.CreateGEP(Casted,
GepIndices.begin(),
GepIndices.end(),
"scevgep");
Ops.push_back(SE.getUnknown(GEP));
- InsertedValues.insert(GEP);
+ rememberInstruction(GEP);
return expand(SE.getAddExpr(Ops));
}
+/// isNonConstantNegative - Return true if the specified scev is negated, but
+/// not a constant.
+static bool isNonConstantNegative(const SCEV *F) {
+ const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(F);
+ if (!Mul) return false;
+
+ // If there is a constant factor, it will be first.
+ const SCEVConstant *SC = dyn_cast<SCEVConstant>(Mul->getOperand(0));
+ if (!SC) return false;
+
+ // Return true if the value is negative, this matches things like (-42 * V).
+ return SC->getValue()->getValue().isNegative();
+}
+
Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) {
int NumOperands = S->getNumOperands();
const Type *Ty = SE.getEffectiveSCEVType(S->getType());
@@ -539,8 +558,14 @@ Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) {
// Emit a bunch of add instructions
for (int i = NumOperands-1; i >= 0; --i) {
if (i == PIdx) continue;
- Value *W = expandCodeFor(S->getOperand(i), Ty);
- V = InsertBinop(Instruction::Add, V, W);
+ const SCEV *Op = S->getOperand(i);
+ if (isNonConstantNegative(Op)) {
+ Value *W = expandCodeFor(SE.getNegativeSCEV(Op), Ty);
+ V = InsertBinop(Instruction::Sub, V, W);
+ } else {
+ Value *W = expandCodeFor(Op, Ty);
+ V = InsertBinop(Instruction::Add, V, W);
+ }
}
return V;
}
@@ -603,7 +628,175 @@ static void ExposePointerBase(const SCEV *&Base, const SCEV *&Rest,
}
}
+/// getAddRecExprPHILiterally - Helper for expandAddRecExprLiterally. Expand
+/// the base addrec, which is the addrec without any non-loop-dominating
+/// values, and return the PHI.
+PHINode *
+SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
+ const Loop *L,
+ const Type *ExpandTy,
+ const Type *IntTy) {
+ // Reuse a previously-inserted PHI, if present.
+ for (BasicBlock::iterator I = L->getHeader()->begin();
+ PHINode *PN = dyn_cast<PHINode>(I); ++I)
+ if (isInsertedInstruction(PN) && SE.getSCEV(PN) == Normalized)
+ return PN;
+
+ // Save the original insertion point so we can restore it when we're done.
+ BasicBlock *SaveInsertBB = Builder.GetInsertBlock();
+ BasicBlock::iterator SaveInsertPt = Builder.GetInsertPoint();
+
+ // Expand code for the start value.
+ Value *StartV = expandCodeFor(Normalized->getStart(), ExpandTy,
+ L->getHeader()->begin());
+
+ // Expand code for the step value. Insert instructions right before the
+ // terminator corresponding to the back-edge. Do this before creating the PHI
+ // so that PHI reuse code doesn't see an incomplete PHI. If the stride is
+ // negative, insert a sub instead of an add for the increment (unless it's a
+ // constant, because subtracts of constants are canonicalized to adds).
+ const SCEV *Step = Normalized->getStepRecurrence(SE);
+ bool isPointer = isa<PointerType>(ExpandTy);
+ bool isNegative = !isPointer && isNonConstantNegative(Step);
+ if (isNegative)
+ Step = SE.getNegativeSCEV(Step);
+ Value *StepV = expandCodeFor(Step, IntTy, L->getHeader()->begin());
+
+ // Create the PHI.
+ Builder.SetInsertPoint(L->getHeader(), L->getHeader()->begin());
+ PHINode *PN = Builder.CreatePHI(ExpandTy, "lsr.iv");
+ rememberInstruction(PN);
+
+ // Create the step instructions and populate the PHI.
+ BasicBlock *Header = L->getHeader();
+ for (pred_iterator HPI = pred_begin(Header), HPE = pred_end(Header);
+ HPI != HPE; ++HPI) {
+ BasicBlock *Pred = *HPI;
+
+ // Add a start value.
+ if (!L->contains(Pred)) {
+ PN->addIncoming(StartV, Pred);
+ continue;
+ }
+
+ // Create a step value and add it to the PHI. If IVIncInsertLoop is
+ // non-null and equal to the addrec's loop, insert the instructions
+ // at IVIncInsertPos.
+ Instruction *InsertPos = L == IVIncInsertLoop ?
+ IVIncInsertPos : Pred->getTerminator();
+ Builder.SetInsertPoint(InsertPos->getParent(), InsertPos);
+ Value *IncV;
+ // If the PHI is a pointer, use a GEP, otherwise use an add or sub.
+ if (isPointer) {
+ const PointerType *GEPPtrTy = cast<PointerType>(ExpandTy);
+ // If the step isn't constant, don't use an implicitly scaled GEP, because
+ // that would require a multiply inside the loop.
+ if (!isa<ConstantInt>(StepV))
+ GEPPtrTy = PointerType::get(Type::getInt1Ty(SE.getContext()),
+ GEPPtrTy->getAddressSpace());
+ const SCEV *const StepArray[1] = { SE.getSCEV(StepV) };
+ IncV = expandAddToGEP(StepArray, StepArray+1, GEPPtrTy, IntTy, PN);
+ if (IncV->getType() != PN->getType()) {
+ IncV = Builder.CreateBitCast(IncV, PN->getType(), "tmp");
+ rememberInstruction(IncV);
+ }
+ } else {
+ IncV = isNegative ?
+ Builder.CreateSub(PN, StepV, "lsr.iv.next") :
+ Builder.CreateAdd(PN, StepV, "lsr.iv.next");
+ rememberInstruction(IncV);
+ }
+ PN->addIncoming(IncV, Pred);
+ }
+
+ // Restore the original insert point.
+ if (SaveInsertBB)
+ Builder.SetInsertPoint(SaveInsertBB, SaveInsertPt);
+
+ // Remember this PHI, even in post-inc mode.
+ InsertedValues.insert(PN);
+
+ return PN;
+}
+
+Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
+ const Type *STy = S->getType();
+ const Type *IntTy = SE.getEffectiveSCEVType(STy);
+ const Loop *L = S->getLoop();
+
+ // Determine a normalized form of this expression, which is the expression
+ // before any post-inc adjustment is made.
+ const SCEVAddRecExpr *Normalized = S;
+ if (L == PostIncLoop) {
+ const SCEV *Step = S->getStepRecurrence(SE);
+ Normalized = cast<SCEVAddRecExpr>(SE.getMinusSCEV(S, Step));
+ }
+
+ // Strip off any non-loop-dominating component from the addrec start.
+ const SCEV *Start = Normalized->getStart();
+ const SCEV *PostLoopOffset = 0;
+ if (!Start->properlyDominates(L->getHeader(), SE.DT)) {
+ PostLoopOffset = Start;
+ Start = SE.getIntegerSCEV(0, Normalized->getType());
+ Normalized =
+ cast<SCEVAddRecExpr>(SE.getAddRecExpr(Start,
+ Normalized->getStepRecurrence(SE),
+ Normalized->getLoop()));
+ }
+
+ // Strip off any non-loop-dominating component from the addrec step.
+ const SCEV *Step = Normalized->getStepRecurrence(SE);
+ const SCEV *PostLoopScale = 0;
+ if (!Step->hasComputableLoopEvolution(L) &&
+ !Step->dominates(L->getHeader(), SE.DT)) {
+ PostLoopScale = Step;
+ Step = SE.getIntegerSCEV(1, Normalized->getType());
+ Normalized =
+ cast<SCEVAddRecExpr>(SE.getAddRecExpr(Start, Step,
+ Normalized->getLoop()));
+ }
+
+ // Expand the core addrec. If we need post-loop scaling, force it to
+ // expand to an integer type to avoid the need for additional casting.
+ const Type *ExpandTy = PostLoopScale ? IntTy : STy;
+ PHINode *PN = getAddRecExprPHILiterally(Normalized, L, ExpandTy, IntTy);
+
+ // Accomodate post-inc mode, if necessary.
+ Value *Result;
+ if (L != PostIncLoop)
+ Result = PN;
+ else {
+ // In PostInc mode, use the post-incremented value.
+ BasicBlock *LatchBlock = L->getLoopLatch();
+ assert(LatchBlock && "PostInc mode requires a unique loop latch!");
+ Result = PN->getIncomingValueForBlock(LatchBlock);
+ }
+
+ // Re-apply any non-loop-dominating scale.
+ if (PostLoopScale) {
+ Result = Builder.CreateMul(Result,
+ expandCodeFor(PostLoopScale, IntTy));
+ rememberInstruction(Result);
+ }
+
+ // Re-apply any non-loop-dominating offset.
+ if (PostLoopOffset) {
+ if (const PointerType *PTy = dyn_cast<PointerType>(ExpandTy)) {
+ const SCEV *const OffsetArray[1] = { PostLoopOffset };
+ Result = expandAddToGEP(OffsetArray, OffsetArray+1, PTy, IntTy, Result);
+ } else {
+ Result = Builder.CreateAdd(Result,
+ expandCodeFor(PostLoopOffset, IntTy));
+ rememberInstruction(Result);
+ }
+ }
+
+ return Result;
+}
+
Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
+ if (!CanonicalMode) return expandAddRecExprLiterally(S);
+
const Type *Ty = SE.getEffectiveSCEVType(S->getType());
const Loop *L = S->getLoop();
@@ -681,17 +874,17 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
// specified loop.
BasicBlock *Header = L->getHeader();
PHINode *PN = PHINode::Create(Ty, "indvar", Header->begin());
- InsertedValues.insert(PN);
+ rememberInstruction(PN);
Constant *One = ConstantInt::get(Ty, 1);
for (pred_iterator HPI = pred_begin(Header), HPE = pred_end(Header);
HPI != HPE; ++HPI)
if (L->contains(*HPI)) {
- // Insert a unit add instruction right before the terminator corresponding
- // to the back-edge.
+ // Insert a unit add instruction right before the terminator
+ // corresponding to the back-edge.
Instruction *Add = BinaryOperator::CreateAdd(PN, One, "indvar.next",
(*HPI)->getTerminator());
- InsertedValues.insert(Add);
+ rememberInstruction(Add);
PN->addIncoming(Add, *HPI);
} else {
PN->addIncoming(Constant::getNullValue(Ty), *HPI);
@@ -738,7 +931,7 @@ Value *SCEVExpander::visitTruncateExpr(const SCEVTruncateExpr *S) {
Value *V = expandCodeFor(S->getOperand(),
SE.getEffectiveSCEVType(S->getOperand()->getType()));
Value *I = Builder.CreateTrunc(V, Ty, "tmp");
- InsertedValues.insert(I);
+ rememberInstruction(I);
return I;
}
@@ -747,7 +940,7 @@ Value *SCEVExpander::visitZeroExtendExpr(const SCEVZeroExtendExpr *S) {
Value *V = expandCodeFor(S->getOperand(),
SE.getEffectiveSCEVType(S->getOperand()->getType()));
Value *I = Builder.CreateZExt(V, Ty, "tmp");
- InsertedValues.insert(I);
+ rememberInstruction(I);
return I;
}
@@ -756,7 +949,7 @@ Value *SCEVExpander::visitSignExtendExpr(const SCEVSignExtendExpr *S) {
Value *V = expandCodeFor(S->getOperand(),
SE.getEffectiveSCEVType(S->getOperand()->getType()));
Value *I = Builder.CreateSExt(V, Ty, "tmp");
- InsertedValues.insert(I);
+ rememberInstruction(I);
return I;
}
@@ -772,9 +965,9 @@ Value *SCEVExpander::visitSMaxExpr(const SCEVSMaxExpr *S) {
}
Value *RHS = expandCodeFor(S->getOperand(i), Ty);
Value *ICmp = Builder.CreateICmpSGT(LHS, RHS, "tmp");
- InsertedValues.insert(ICmp);
+ rememberInstruction(ICmp);
Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "smax");
- InsertedValues.insert(Sel);
+ rememberInstruction(Sel);
LHS = Sel;
}
// In the case of mixed integer and pointer types, cast the
@@ -796,9 +989,9 @@ Value *SCEVExpander::visitUMaxExpr(const SCEVUMaxExpr *S) {
}
Value *RHS = expandCodeFor(S->getOperand(i), Ty);
Value *ICmp = Builder.CreateICmpUGT(LHS, RHS, "tmp");
- InsertedValues.insert(ICmp);
+ rememberInstruction(ICmp);
Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "umax");
- InsertedValues.insert(Sel);
+ rememberInstruction(Sel);
LHS = Sel;
}
// In the case of mixed integer and pointer types, cast the
@@ -863,7 +1056,8 @@ Value *SCEVExpander::expand(const SCEV *S) {
Value *V = visit(S);
// Remember the expanded value for this SCEV at this location.
- InsertedExpressions[std::make_pair(S, InsertPt)] = V;
+ if (!PostIncLoop)
+ InsertedExpressions[std::make_pair(S, InsertPt)] = V;
Builder.SetInsertPoint(SaveInsertBB, SaveInsertPt);
return V;
diff --git a/lib/Archive/Makefile b/lib/Archive/Makefile
index da97804..1256e1c 100644
--- a/lib/Archive/Makefile
+++ b/lib/Archive/Makefile
@@ -9,6 +9,7 @@
LEVEL = ../..
LIBRARYNAME = LLVMArchive
+CXXFLAGS = -fno-rtti
# We only want an archive so only those modules actually used by a tool are
# included.
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 8ad658d..2a926d2 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -558,7 +558,6 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(readnone);
KEYWORD(readonly);
- KEYWORD(inlinehint);
KEYWORD(noinline);
KEYWORD(alwaysinline);
KEYWORD(optsize);
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index e4039ab..04a5263c 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -947,7 +947,6 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) {
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;
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index bea0593..85c07ff 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -29,7 +29,6 @@ namespace llvm {
class Instruction;
class Constant;
class GlobalValue;
- class MetadataBase;
class MDString;
class MDNode;
diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h
index 7f1807c..80eb194 100644
--- a/lib/AsmParser/LLToken.h
+++ b/lib/AsmParser/LLToken.h
@@ -85,7 +85,6 @@ namespace lltok {
kw_readnone,
kw_readonly,
- kw_inlinehint,
kw_noinline,
kw_alwaysinline,
kw_optsize,
diff --git a/lib/AsmParser/Makefile b/lib/AsmParser/Makefile
index 995bb0e..7b53a87 100644
--- a/lib/AsmParser/Makefile
+++ b/lib/AsmParser/Makefile
@@ -10,5 +10,6 @@
LEVEL = ../..
LIBRARYNAME := LLVMAsmParser
BUILD_ARCHIVE = 1
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/AsmParser/Parser.cpp b/lib/AsmParser/Parser.cpp
index 331a233..aac4027 100644
--- a/lib/AsmParser/Parser.cpp
+++ b/lib/AsmParser/Parser.cpp
@@ -45,7 +45,8 @@ Module *llvm::ParseAssemblyFile(const std::string &Filename, SMDiagnostic &Err,
MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrorStr);
if (F == 0) {
Err = SMDiagnostic("", -1, -1,
- "Could not open input file '" + Filename + "'", "");
+ "Could not open input file '" + Filename + "': " +
+ ErrorStr, "");
return 0;
}
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index aabbc90..2549a51 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1167,7 +1167,7 @@ bool BitcodeReader::ParseConstants() {
Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy);
- if (OpTy->isFloatingPoint())
+ if (OpTy->isFPOrFPVector())
V = ConstantExpr::getFCmp(Record[3], Op0, Op1);
else
V = ConstantExpr::getICmp(Record[3], Op0, Op1);
diff --git a/lib/Bitcode/Reader/Makefile b/lib/Bitcode/Reader/Makefile
index 59af8d53..0aae3bf 100644
--- a/lib/Bitcode/Reader/Makefile
+++ b/lib/Bitcode/Reader/Makefile
@@ -10,6 +10,7 @@
LEVEL = ../../..
LIBRARYNAME = LLVMBitReader
BUILD_ARCHIVE = 1
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Bitcode/Writer/Makefile b/lib/Bitcode/Writer/Makefile
index 7b0bd72..5f9742e 100644
--- a/lib/Bitcode/Writer/Makefile
+++ b/lib/Bitcode/Writer/Makefile
@@ -10,6 +10,7 @@
LEVEL = ../../..
LIBRARYNAME = LLVMBitWriter
BUILD_ARCHIVE = 1
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp
index cb139e5..c46d735 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -140,7 +140,7 @@ void ValueEnumerator::setInstructionID(const Instruction *I) {
}
unsigned ValueEnumerator::getValueID(const Value *V) const {
- if (isa<MetadataBase>(V)) {
+ if (isa<MDNode>(V) || isa<MDString>(V)) {
ValueMapType::const_iterator I = MDValueMap.find(V);
assert(I != MDValueMap.end() && "Value not in slotcalculator!");
return I->second-1;
@@ -229,7 +229,8 @@ void ValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) {
MDValueMap[MD] = Values.size();
}
-void ValueEnumerator::EnumerateMetadata(const MetadataBase *MD) {
+void ValueEnumerator::EnumerateMetadata(const Value *MD) {
+ assert((isa<MDNode>(MD) || isa<MDString>(MD)) && "Invalid metadata kind");
// Check to see if it's already in!
unsigned &MDValueID = MDValueMap[MD];
if (MDValueID) {
@@ -262,8 +263,8 @@ void ValueEnumerator::EnumerateMetadata(const MetadataBase *MD) {
void ValueEnumerator::EnumerateValue(const Value *V) {
assert(!V->getType()->isVoidTy() && "Can't insert void values!");
- if (const MetadataBase *MB = dyn_cast<MetadataBase>(V))
- return EnumerateMetadata(MB);
+ if (isa<MDNode>(V) || isa<MDString>(V))
+ return EnumerateMetadata(V);
else if (const NamedMDNode *NMD = dyn_cast<NamedMDNode>(V))
return EnumerateNamedMDNode(NMD);
diff --git a/lib/Bitcode/Writer/ValueEnumerator.h b/lib/Bitcode/Writer/ValueEnumerator.h
index c50fe9c..4f8ebf5 100644
--- a/lib/Bitcode/Writer/ValueEnumerator.h
+++ b/lib/Bitcode/Writer/ValueEnumerator.h
@@ -127,7 +127,7 @@ public:
private:
void OptimizeConstants(unsigned CstStart, unsigned CstEnd);
- void EnumerateMetadata(const MetadataBase *MD);
+ void EnumerateMetadata(const Value *MD);
void EnumerateNamedMDNode(const NamedMDNode *NMD);
void EnumerateValue(const Value *V);
void EnumerateType(const Type *T);
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 876f628..f4d8864 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -16,6 +16,7 @@
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
#include "llvm/Module.h"
+#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/GCMetadataPrinter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
@@ -23,18 +24,19 @@
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLowering.h"
@@ -43,7 +45,6 @@
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.h"
#include <cerrno>
using namespace llvm;
@@ -51,6 +52,15 @@ static cl::opt<cl::boolOrDefault>
AsmVerbose("asm-verbose", cl::desc("Add comments to directives."),
cl::init(cl::BOU_UNSET));
+static bool getVerboseAsm(bool VDef) {
+ switch (AsmVerbose) {
+ default:
+ case cl::BOU_UNSET: return VDef;
+ case cl::BOU_TRUE: return true;
+ case cl::BOU_FALSE: return false;
+ }
+}
+
char AsmPrinter::ID = 0;
AsmPrinter::AsmPrinter(formatted_raw_ostream &o, TargetMachine &tm,
const MCAsmInfo *T, bool VDef)
@@ -59,16 +69,13 @@ AsmPrinter::AsmPrinter(formatted_raw_ostream &o, TargetMachine &tm,
OutContext(*new MCContext()),
// FIXME: Pass instprinter to streamer.
- OutStreamer(*createAsmStreamer(OutContext, O, *T, 0)),
+ OutStreamer(*createAsmStreamer(OutContext, O, *T,
+ TM.getTargetData()->isLittleEndian(),
+ getVerboseAsm(VDef), 0)),
- LastMI(0), LastFn(0), Counter(~0U),
- PrevDLT(0, 0, ~0U, ~0U) {
+ LastMI(0), LastFn(0), Counter(~0U), PrevDLT(NULL) {
DW = 0; MMI = 0;
- switch (AsmVerbose) {
- case cl::BOU_UNSET: VerboseAsm = VDef; break;
- case cl::BOU_TRUE: VerboseAsm = true; break;
- case cl::BOU_FALSE: VerboseAsm = false; break;
- }
+ VerboseAsm = getVerboseAsm(VDef);
}
AsmPrinter::~AsmPrinter() {
@@ -103,22 +110,15 @@ bool AsmPrinter::doInitialization(Module &M) {
const_cast<TargetLoweringObjectFile&>(getObjFileLowering())
.Initialize(OutContext, TM);
- Mang = new Mangler(M, MAI->getGlobalPrefix(), MAI->getPrivateGlobalPrefix(),
- MAI->getLinkerPrivateGlobalPrefix());
-
- if (MAI->doesAllowQuotesInName())
- Mang->setUseQuotes(true);
-
- if (MAI->doesAllowNameToStartWithDigit())
- Mang->setSymbolsCanStartWithDigit(true);
+ Mang = new Mangler(*MAI);
// Allow the target to emit any magic that it wants at the start of the file.
EmitStartOfAsmFile(M);
if (MAI->hasSingleParameterDotFile()) {
- /* Very minimal debug info. It is ignored if we emit actual
- debug info. If we don't, this at least helps the user find where
- a function came from. */
+ // Very minimal debug info. It is ignored if we emit actual
+ // debug info. If we don't, this at least helps the user find where
+ // a function came from.
O << "\t.file\t\"" << M.getModuleIdentifier() << "\"\n";
}
@@ -144,11 +144,148 @@ bool AsmPrinter::doInitialization(Module &M) {
return false;
}
+/// EmitGlobalVariable - Emit the specified global variable to the .s file.
+void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
+ if (!GV->hasInitializer()) // External globals require no code.
+ return;
+
+ // Check to see if this is a special global used by LLVM, if so, emit it.
+ if (EmitSpecialLLVMGlobal(GV))
+ return;
+
+ MCSymbol *GVSym = GetGlobalValueSymbol(GV);
+ printVisibility(GVSym, GV->getVisibility());
+
+ if (MAI->hasDotTypeDotSizeDirective()) {
+ O << "\t.type\t" << *GVSym;
+ if (MAI->getCommentString()[0] != '@')
+ O << ",@object\n";
+ else
+ O << ",%object\n";
+ }
+
+ SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM);
+
+ const TargetData *TD = TM.getTargetData();
+ unsigned Size = TD->getTypeAllocSize(GV->getType()->getElementType());
+ unsigned AlignLog = TD->getPreferredAlignmentLog(GV);
+
+ // Handle common and BSS local symbols (.lcomm).
+ if (GVKind.isCommon() || GVKind.isBSSLocal()) {
+ if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
+
+ if (VerboseAsm) {
+ WriteAsOperand(OutStreamer.GetCommentOS(), GV,
+ /*PrintType=*/false, GV->getParent());
+ OutStreamer.GetCommentOS() << '\n';
+ }
+
+ // Handle common symbols.
+ if (GVKind.isCommon()) {
+ // .comm _foo, 42, 4
+ OutStreamer.EmitCommonSymbol(GVSym, Size, 1 << AlignLog);
+ return;
+ }
+
+ // Handle local BSS symbols.
+ if (MAI->hasMachoZeroFillDirective()) {
+ const MCSection *TheSection =
+ getObjFileLowering().SectionForGlobal(GV, GVKind, Mang, TM);
+ // .zerofill __DATA, __bss, _foo, 400, 5
+ OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog);
+ return;
+ }
+
+ if (MAI->hasLCOMMDirective()) {
+ // .lcomm _foo, 42
+ OutStreamer.EmitLocalCommonSymbol(GVSym, Size);
+ return;
+ }
+
+ // .local _foo
+ OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Local);
+ // .comm _foo, 42, 4
+ OutStreamer.EmitCommonSymbol(GVSym, Size, 1 << AlignLog);
+ return;
+ }
+
+ const MCSection *TheSection =
+ getObjFileLowering().SectionForGlobal(GV, GVKind, Mang, TM);
+
+ // Handle the zerofill directive on darwin, which is a special form of BSS
+ // emission.
+ if (GVKind.isBSSExtern() && MAI->hasMachoZeroFillDirective()) {
+ // .globl _foo
+ OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
+ // .zerofill __DATA, __common, _foo, 400, 5
+ OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog);
+ return;
+ }
+
+ OutStreamer.SwitchSection(TheSection);
+
+ // TODO: Factor into an 'emit linkage' thing that is shared with function
+ // bodies.
+ switch (GV->getLinkage()) {
+ case GlobalValue::CommonLinkage:
+ case GlobalValue::LinkOnceAnyLinkage:
+ case GlobalValue::LinkOnceODRLinkage:
+ case GlobalValue::WeakAnyLinkage:
+ case GlobalValue::WeakODRLinkage:
+ case GlobalValue::LinkerPrivateLinkage:
+ if (MAI->getWeakDefDirective() != 0) {
+ // .globl _foo
+ OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
+ // .weak_definition _foo
+ OutStreamer.EmitSymbolAttribute(GVSym, MCSA_WeakDefinition);
+ } else if (const char *LinkOnce = MAI->getLinkOnceDirective()) {
+ // .globl _foo
+ OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
+ // .linkonce same_size
+ O << LinkOnce;
+ } else {
+ // .weak _foo
+ OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak);
+ }
+ break;
+ case GlobalValue::DLLExportLinkage:
+ case GlobalValue::AppendingLinkage:
+ // FIXME: appending linkage variables should go into a section of
+ // their name or something. For now, just emit them as external.
+ case GlobalValue::ExternalLinkage:
+ // If external or appending, declare as a global symbol.
+ // .globl _foo
+ OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
+ break;
+ case GlobalValue::PrivateLinkage:
+ case GlobalValue::InternalLinkage:
+ break;
+ default:
+ llvm_unreachable("Unknown linkage type!");
+ }
+
+ EmitAlignment(AlignLog, GV);
+ if (VerboseAsm) {
+ WriteAsOperand(OutStreamer.GetCommentOS(), GV,
+ /*PrintType=*/false, GV->getParent());
+ OutStreamer.GetCommentOS() << '\n';
+ }
+ OutStreamer.EmitLabel(GVSym);
+
+ EmitGlobalConstant(GV->getInitializer());
+
+ if (MAI->hasDotTypeDotSizeDirective())
+ O << "\t.size\t" << *GVSym << ", " << Size << '\n';
+
+ OutStreamer.AddBlankLine();
+}
+
+
bool AsmPrinter::doFinalization(Module &M) {
// Emit global variables.
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I)
- PrintGlobalVariable(I);
+ EmitGlobalVariable(I);
// Emit final debug information.
if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling())
@@ -164,35 +301,37 @@ bool AsmPrinter::doFinalization(Module &M) {
// Print out module-level global variables here.
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) {
- if (I->hasExternalWeakLinkage())
- O << MAI->getWeakRefDirective() << Mang->getMangledName(I) << '\n';
+ if (!I->hasExternalWeakLinkage()) continue;
+ OutStreamer.EmitSymbolAttribute(GetGlobalValueSymbol(I),
+ MCSA_WeakReference);
}
for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) {
- if (I->hasExternalWeakLinkage())
- O << MAI->getWeakRefDirective() << Mang->getMangledName(I) << '\n';
+ if (!I->hasExternalWeakLinkage()) continue;
+ OutStreamer.EmitSymbolAttribute(GetGlobalValueSymbol(I),
+ MCSA_WeakReference);
}
}
if (MAI->getSetDirective()) {
- O << '\n';
+ OutStreamer.AddBlankLine();
for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
I != E; ++I) {
- std::string Name = Mang->getMangledName(I);
+ MCSymbol *Name = GetGlobalValueSymbol(I);
const GlobalValue *GV = cast<GlobalValue>(I->getAliasedGlobal());
- std::string Target = Mang->getMangledName(GV);
+ MCSymbol *Target = GetGlobalValueSymbol(GV);
if (I->hasExternalLinkage() || !MAI->getWeakRefDirective())
- O << "\t.globl\t" << Name << '\n';
+ OutStreamer.EmitSymbolAttribute(Name, MCSA_Global);
else if (I->hasWeakLinkage())
- O << MAI->getWeakRefDirective() << Name << '\n';
- else if (!I->hasLocalLinkage())
- llvm_unreachable("Invalid alias linkage");
+ OutStreamer.EmitSymbolAttribute(Name, MCSA_WeakReference);
+ else
+ assert(I->hasLocalLinkage() && "Invalid alias linkage");
printVisibility(Name, I->getVisibility());
- O << MAI->getSetDirective() << ' ' << Name << ", " << Target << '\n';
+ O << MAI->getSetDirective() << ' ' << *Name << ", " << *Target << '\n';
}
}
@@ -206,9 +345,8 @@ bool AsmPrinter::doFinalization(Module &M) {
// to be executable. Some targets have a directive to declare this.
Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline");
if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty())
- if (MAI->getNonexecutableStackDirective())
- O << MAI->getNonexecutableStackDirective() << '\n';
-
+ if (MCSection *S = MAI->getNonexecutableStackSection(OutContext))
+ OutStreamer.SwitchSection(S);
// Allow the target to emit any magic that it wants at the end of the file,
// after everything else has gone out.
@@ -222,8 +360,8 @@ bool AsmPrinter::doFinalization(Module &M) {
}
void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
- // What's my mangled name?
- CurrentFnName = Mang->getMangledName(MF.getFunction());
+ // Get the function symbol.
+ CurrentFnSym = GetGlobalValueSymbol(MF.getFunction());
IncrementFunctionNumber();
if (VerboseAsm)
@@ -307,19 +445,20 @@ void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) {
// Emit inter-object padding for alignment.
unsigned AlignMask = CPE.getAlignment() - 1;
unsigned NewOffset = (Offset + AlignMask) & ~AlignMask;
- EmitZeros(NewOffset - Offset);
+ OutStreamer.EmitFill(NewOffset - Offset, 0/*fillval*/, 0/*addrspace*/);
const Type *Ty = CPE.getType();
Offset = NewOffset + TM.getTargetData()->getTypeAllocSize(Ty);
- O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
- << CPI << ':';
+ // Emit the label with a comment on it.
if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << " constant ";
- WriteTypeSymbolic(O, CPE.getType(), MF->getFunction()->getParent());
+ OutStreamer.GetCommentOS() << "constant pool ";
+ WriteTypeSymbolic(OutStreamer.GetCommentOS(), CPE.getType(),
+ MF->getFunction()->getParent());
+ OutStreamer.GetCommentOS() << '\n';
}
- O << '\n';
+ OutStreamer.EmitLabel(GetCPISymbol(CPI));
+
if (CPE.isMachineConstantPoolEntry())
EmitMachineConstantPoolValue(CPE.Val.MachineCPVal);
else
@@ -381,14 +520,11 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI,
// before each jump table. The first label is never referenced, but tells
// the assembler and linker the extents of the jump table object. The
// second label is actually referenced by the code.
- if (JTInDiffSection && MAI->getLinkerPrivateGlobalPrefix()[0]) {
- O << MAI->getLinkerPrivateGlobalPrefix()
- << "JTI" << getFunctionNumber() << '_' << i << ":\n";
- }
-
- O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
- << '_' << i << ":\n";
-
+ if (JTInDiffSection && MAI->getLinkerPrivateGlobalPrefix()[0])
+ OutStreamer.EmitLabel(GetJTISymbol(i, true));
+
+ OutStreamer.EmitLabel(GetJTISymbol(i));
+
for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) {
printPICJumpTableEntry(MJTI, JTBBs[ii], i);
O << '\n';
@@ -418,17 +554,16 @@ void AsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI,
// If we're emitting non-PIC code, then emit the entries as direct
// references to the target basic blocks.
if (!isPIC) {
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MBB->getNumber());
} else if (MAI->getSetDirective()) {
O << MAI->getPrivateGlobalPrefix() << getFunctionNumber()
<< '_' << uid << "_set_" << MBB->getNumber();
} else {
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MBB->getNumber());
// If the arch uses custom Jump Table directives, don't calc relative to
- // JT
+ // JT.
if (!HadJTEntryDirective)
- O << '-' << MAI->getPrivateGlobalPrefix() << "JTI"
- << getFunctionNumber() << '_' << uid;
+ O << '-' << *GetJTISymbol(uid);
}
}
@@ -438,7 +573,7 @@ void AsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI,
/// do nothing and return false.
bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
if (GV->getName() == "llvm.used") {
- if (MAI->getUsedDirective() != 0) // No need to emit this at all.
+ if (MAI->hasNoDeadStrip()) // No need to emit this at all.
EmitLLVMUsedList(GV->getInitializer());
return true;
}
@@ -458,6 +593,13 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
OutStreamer.SwitchSection(getObjFileLowering().getStaticCtorSection());
EmitAlignment(Align, 0);
EmitXXStructorList(GV->getInitializer());
+
+ if (TM.getRelocationModel() == Reloc::Static &&
+ MAI->hasStaticCtorDtorReferenceInStaticMode()) {
+ StringRef Sym(".constructors_used");
+ OutStreamer.EmitSymbolAttribute(OutContext.GetOrCreateSymbol(Sym),
+ MCSA_Reference);
+ }
return true;
}
@@ -465,6 +607,13 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
OutStreamer.SwitchSection(getObjFileLowering().getStaticDtorSection());
EmitAlignment(Align, 0);
EmitXXStructorList(GV->getInitializer());
+
+ if (TM.getRelocationModel() == Reloc::Static &&
+ MAI->hasStaticCtorDtorReferenceInStaticMode()) {
+ StringRef Sym(".destructors_used");
+ OutStreamer.EmitSymbolAttribute(OutContext.GetOrCreateSymbol(Sym),
+ MCSA_Reference);
+ }
return true;
}
@@ -475,8 +624,6 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
/// global in the specified llvm.used list for which emitUsedDirectiveFor
/// is true, as being used with this directive.
void AsmPrinter::EmitLLVMUsedList(Constant *List) {
- const char *Directive = MAI->getUsedDirective();
-
// Should be an array of 'i8*'.
ConstantArray *InitList = dyn_cast<ConstantArray>(List);
if (InitList == 0) return;
@@ -484,11 +631,9 @@ void AsmPrinter::EmitLLVMUsedList(Constant *List) {
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
const GlobalValue *GV =
dyn_cast<GlobalValue>(InitList->getOperand(i)->stripPointerCasts());
- if (GV && getObjFileLowering().shouldEmitUsedDirectiveFor(GV, Mang)) {
- O << Directive;
- EmitConstantValueOnly(InitList->getOperand(i));
- O << '\n';
- }
+ if (GV && getObjFileLowering().shouldEmitUsedDirectiveFor(GV, Mang))
+ OutStreamer.EmitSymbolAttribute(GetGlobalValueSymbol(GV),
+ MCSA_NoDeadStrip);
}
}
@@ -510,189 +655,35 @@ void AsmPrinter::EmitXXStructorList(Constant *List) {
}
}
-
-//===----------------------------------------------------------------------===//
-/// LEB 128 number encoding.
-
-/// PrintULEB128 - Print a series of hexadecimal values (separated by commas)
-/// representing an unsigned leb128 value.
-void AsmPrinter::PrintULEB128(unsigned Value) const {
- char Buffer[20];
- do {
- unsigned char Byte = static_cast<unsigned char>(Value & 0x7f);
- Value >>= 7;
- if (Value) Byte |= 0x80;
- O << "0x" << utohex_buffer(Byte, Buffer+20);
- if (Value) O << ", ";
- } while (Value);
-}
-
-/// PrintSLEB128 - Print a series of hexadecimal values (separated by commas)
-/// representing a signed leb128 value.
-void AsmPrinter::PrintSLEB128(int Value) const {
- int Sign = Value >> (8 * sizeof(Value) - 1);
- bool IsMore;
- char Buffer[20];
-
- do {
- unsigned char Byte = static_cast<unsigned char>(Value & 0x7f);
- Value >>= 7;
- IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
- if (IsMore) Byte |= 0x80;
- O << "0x" << utohex_buffer(Byte, Buffer+20);
- if (IsMore) O << ", ";
- } while (IsMore);
-}
-
//===--------------------------------------------------------------------===//
// Emission and print routines
//
-/// PrintHex - Print a value as a hexadecimal value.
-///
-void AsmPrinter::PrintHex(int Value) const {
- char Buffer[20];
- O << "0x" << utohex_buffer(static_cast<unsigned>(Value), Buffer+20);
-}
-
-/// EOL - Print a newline character to asm stream. If a comment is present
-/// then it will be printed first. Comments should not contain '\n'.
-void AsmPrinter::EOL() const {
- O << '\n';
-}
-
-void AsmPrinter::EOL(const std::string &Comment) const {
- if (VerboseAsm && !Comment.empty()) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << ' '
- << Comment;
- }
- O << '\n';
-}
-
-void AsmPrinter::EOL(const char* Comment) const {
- if (VerboseAsm && *Comment) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << ' '
- << Comment;
- }
- O << '\n';
-}
-
-static const char *DecodeDWARFEncoding(unsigned Encoding) {
- switch (Encoding) {
- case dwarf::DW_EH_PE_absptr:
- return "absptr";
- case dwarf::DW_EH_PE_omit:
- return "omit";
- case dwarf::DW_EH_PE_pcrel:
- return "pcrel";
- case dwarf::DW_EH_PE_udata4:
- return "udata4";
- case dwarf::DW_EH_PE_udata8:
- return "udata8";
- case dwarf::DW_EH_PE_sdata4:
- return "sdata4";
- case dwarf::DW_EH_PE_sdata8:
- return "sdata8";
- case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4:
- return "pcrel udata4";
- case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4:
- return "pcrel sdata4";
- case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8:
- return "pcrel udata8";
- case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8:
- return "pcrel sdata8";
- case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata4:
- return "indirect pcrel udata4";
- case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata4:
- return "indirect pcrel sdata4";
- case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata8:
- return "indirect pcrel udata8";
- case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata8:
- return "indirect pcrel sdata8";
- }
-
- return 0;
-}
-
-void AsmPrinter::EOL(const char *Comment, unsigned Encoding) const {
- if (VerboseAsm && *Comment) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << ' '
- << Comment;
-
- if (const char *EncStr = DecodeDWARFEncoding(Encoding))
- O << " (" << EncStr << ')';
- }
- O << '\n';
-}
-
-/// EmitULEB128Bytes - Emit an assembler byte data directive to compose an
-/// unsigned leb128 value.
-void AsmPrinter::EmitULEB128Bytes(unsigned Value) const {
- if (MAI->hasLEB128()) {
- O << "\t.uleb128\t"
- << Value;
- } else {
- O << MAI->getData8bitsDirective();
- PrintULEB128(Value);
- }
-}
-
-/// EmitSLEB128Bytes - print an assembler byte data directive to compose a
-/// signed leb128 value.
-void AsmPrinter::EmitSLEB128Bytes(int Value) const {
- if (MAI->hasLEB128()) {
- O << "\t.sleb128\t"
- << Value;
- } else {
- O << MAI->getData8bitsDirective();
- PrintSLEB128(Value);
- }
-}
-
/// EmitInt8 - Emit a byte directive and value.
///
void AsmPrinter::EmitInt8(int Value) const {
- O << MAI->getData8bitsDirective();
- PrintHex(Value & 0xFF);
+ OutStreamer.EmitIntValue(Value, 1, 0/*addrspace*/);
}
/// EmitInt16 - Emit a short directive and value.
///
void AsmPrinter::EmitInt16(int Value) const {
- O << MAI->getData16bitsDirective();
- PrintHex(Value & 0xFFFF);
+ OutStreamer.EmitIntValue(Value, 2, 0/*addrspace*/);
}
/// EmitInt32 - Emit a long directive and value.
///
void AsmPrinter::EmitInt32(int Value) const {
- O << MAI->getData32bitsDirective();
- PrintHex(Value);
+ OutStreamer.EmitIntValue(Value, 4, 0/*addrspace*/);
}
/// EmitInt64 - Emit a long long directive and value.
///
void AsmPrinter::EmitInt64(uint64_t Value) const {
- if (MAI->getData64bitsDirective()) {
- O << MAI->getData64bitsDirective();
- PrintHex(Value);
- } else {
- if (TM.getTargetData()->isBigEndian()) {
- EmitInt32(unsigned(Value >> 32)); O << '\n';
- EmitInt32(unsigned(Value));
- } else {
- EmitInt32(unsigned(Value)); O << '\n';
- EmitInt32(unsigned(Value >> 32));
- }
- }
+ OutStreamer.EmitIntValue(Value, 8, 0/*addrspace*/);
}
+
/// toOctal - Convert the low order bits of X into an octal digit.
///
static inline char toOctal(int X) {
@@ -725,31 +716,8 @@ static void printStringChar(formatted_raw_ostream &O, unsigned char C) {
}
}
-/// EmitString - Emit a string with quotes and a null terminator.
-/// Special characters are emitted properly.
-/// \literal (Eg. '\t') \endliteral
-void AsmPrinter::EmitString(const StringRef String) const {
- EmitString(String.data(), String.size());
-}
-
-void AsmPrinter::EmitString(const char *String, unsigned Size) const {
- const char* AscizDirective = MAI->getAscizDirective();
- if (AscizDirective)
- O << AscizDirective;
- else
- O << MAI->getAsciiDirective();
- O << '\"';
- for (unsigned i = 0; i < Size; ++i)
- printStringChar(O, String[i]);
- if (AscizDirective)
- O << '\"';
- else
- O << "\\0\"";
-}
-
-
/// EmitFile - Emit a .file directive.
-void AsmPrinter::EmitFile(unsigned Number, const std::string &Name) const {
+void AsmPrinter::EmitFile(unsigned Number, StringRef Name) const {
O << "\t.file\t" << Number << " \"";
for (unsigned i = 0, N = Name.size(); i < N; ++i)
printStringChar(O, Name[i]);
@@ -788,52 +756,26 @@ void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV,
OutStreamer.EmitValueToAlignment(1 << NumBits, FillValue, 1, 0);
}
-/// EmitZeros - Emit a block of zeros.
+/// LowerConstant - Lower the specified LLVM Constant to an MCExpr.
///
-void AsmPrinter::EmitZeros(uint64_t NumZeros, unsigned AddrSpace) const {
- if (NumZeros) {
- if (MAI->getZeroDirective()) {
- O << MAI->getZeroDirective() << NumZeros;
- if (MAI->getZeroDirectiveSuffix())
- O << MAI->getZeroDirectiveSuffix();
- O << '\n';
- } else {
- for (; NumZeros; --NumZeros)
- O << MAI->getData8bitsDirective(AddrSpace) << "0\n";
- }
- }
-}
-
-// Print out the specified constant, without a storage class. Only the
-// constants valid in constant expressions can occur here.
-void AsmPrinter::EmitConstantValueOnly(const Constant *CV) {
- if (CV->isNullValue() || isa<UndefValue>(CV)) {
- O << '0';
- return;
- }
-
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
- O << CI->getZExtValue();
- return;
- }
+static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) {
+ MCContext &Ctx = AP.OutContext;
- if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
- // This is a constant address for a global variable or function. Use the
- // name of the variable or function as the address value.
- O << Mang->getMangledName(GV);
- return;
- }
+ if (CV->isNullValue() || isa<UndefValue>(CV))
+ return MCConstantExpr::Create(0, Ctx);
+
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV))
+ return MCConstantExpr::Create(CI->getZExtValue(), Ctx);
- if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) {
- GetBlockAddressSymbol(BA)->print(O, MAI);
- return;
- }
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV))
+ return MCSymbolRefExpr::Create(AP.GetGlobalValueSymbol(GV), Ctx);
+ if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV))
+ return MCSymbolRefExpr::Create(AP.GetBlockAddressSymbol(BA), Ctx);
const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV);
if (CE == 0) {
- llvm_unreachable("Unknown constant value!");
- O << '0';
- return;
+ llvm_unreachable("Unknown constant value to lower!");
+ return MCConstantExpr::Create(0, Ctx);
}
switch (CE->getOpcode()) {
@@ -845,406 +787,214 @@ void AsmPrinter::EmitConstantValueOnly(const Constant *CV) {
case Instruction::SIToFP:
case Instruction::FPToUI:
case Instruction::FPToSI:
- default:
- llvm_unreachable("FIXME: Don't support this constant cast expr");
+ default: llvm_unreachable("FIXME: Don't support this constant cast expr");
case Instruction::GetElementPtr: {
- // generate a symbolic expression for the byte address
- const TargetData *TD = TM.getTargetData();
- const Constant *ptrVal = CE->getOperand(0);
- SmallVector<Value*, 8> idxVec(CE->op_begin()+1, CE->op_end());
- int64_t Offset = TD->getIndexedOffset(ptrVal->getType(), &idxVec[0],
- idxVec.size());
+ const TargetData &TD = *AP.TM.getTargetData();
+ // 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());
+ int64_t Offset = TD.getIndexedOffset(PtrVal->getType(), &IdxVec[0],
+ IdxVec.size());
+
+ const MCExpr *Base = LowerConstant(CE->getOperand(0), AP);
if (Offset == 0)
- return EmitConstantValueOnly(ptrVal);
+ return Base;
// Truncate/sext the offset to the pointer size.
- if (TD->getPointerSizeInBits() != 64) {
- int SExtAmount = 64-TD->getPointerSizeInBits();
+ if (TD.getPointerSizeInBits() != 64) {
+ int SExtAmount = 64-TD.getPointerSizeInBits();
Offset = (Offset << SExtAmount) >> SExtAmount;
}
- if (Offset)
- O << '(';
- EmitConstantValueOnly(ptrVal);
- if (Offset > 0)
- O << ") + " << Offset;
- else
- O << ") - " << -Offset;
- return;
+ return MCBinaryExpr::CreateAdd(Base, MCConstantExpr::Create(Offset, Ctx),
+ Ctx);
}
+
+ case Instruction::Trunc:
+ // We emit the value and depend on the assembler to truncate the generated
+ // expression properly. This is important for differences between
+ // blockaddress labels. Since the two labels are in the same function, it
+ // is reasonable to treat their delta as a 32-bit value.
+ // FALL THROUGH.
case Instruction::BitCast:
- return EmitConstantValueOnly(CE->getOperand(0));
+ return LowerConstant(CE->getOperand(0), AP);
case Instruction::IntToPtr: {
+ const TargetData &TD = *AP.TM.getTargetData();
// Handle casts to pointers by changing them into casts to the appropriate
// integer type. This promotes constant folding and simplifies this code.
- const TargetData *TD = TM.getTargetData();
Constant *Op = CE->getOperand(0);
- Op = ConstantExpr::getIntegerCast(Op, TD->getIntPtrType(CV->getContext()),
+ Op = ConstantExpr::getIntegerCast(Op, TD.getIntPtrType(CV->getContext()),
false/*ZExt*/);
- return EmitConstantValueOnly(Op);
+ return LowerConstant(Op, AP);
}
case Instruction::PtrToInt: {
+ const TargetData &TD = *AP.TM.getTargetData();
// 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);
const Type *Ty = CE->getType();
- const TargetData *TD = TM.getTargetData();
+
+ const MCExpr *OpExpr = LowerConstant(Op, AP);
// We can emit the pointer value into this slot if the slot is an
- // integer slot greater or equal to the size of the pointer.
- if (TD->getTypeAllocSize(Ty) == TD->getTypeAllocSize(Op->getType()))
- return EmitConstantValueOnly(Op);
-
- O << "((";
- EmitConstantValueOnly(Op);
- APInt ptrMask =
- APInt::getAllOnesValue(TD->getTypeAllocSizeInBits(Op->getType()));
-
- SmallString<40> S;
- ptrMask.toStringUnsigned(S);
- O << ") & " << S.str() << ')';
- return;
+ // integer slot equal to the size of the pointer.
+ if (TD.getTypeAllocSize(Ty) == TD.getTypeAllocSize(Op->getType()))
+ return OpExpr;
+
+ // Otherwise the pointer is smaller than the resultant integer, mask off
+ // the high bits so we are sure to get a proper truncation if the input is
+ // a constant expr.
+ unsigned InBits = TD.getTypeAllocSizeInBits(Op->getType());
+ const MCExpr *MaskExpr = MCConstantExpr::Create(~0ULL >> (64-InBits), Ctx);
+ return MCBinaryExpr::CreateAnd(OpExpr, MaskExpr, Ctx);
}
- case Instruction::Trunc:
- // We emit the value and depend on the assembler to truncate the generated
- // expression properly. This is important for differences between
- // blockaddress labels. Since the two labels are in the same function, it
- // is reasonable to treat their delta as a 32-bit value.
- return EmitConstantValueOnly(CE->getOperand(0));
-
case Instruction::Add:
case Instruction::Sub:
case Instruction::And:
case Instruction::Or:
- case Instruction::Xor:
- O << '(';
- EmitConstantValueOnly(CE->getOperand(0));
- O << ')';
+ case Instruction::Xor: {
+ const MCExpr *LHS = LowerConstant(CE->getOperand(0), AP);
+ const MCExpr *RHS = LowerConstant(CE->getOperand(1), AP);
switch (CE->getOpcode()) {
- case Instruction::Add:
- O << " + ";
- break;
- case Instruction::Sub:
- O << " - ";
- break;
- case Instruction::And:
- O << " & ";
- break;
- case Instruction::Or:
- O << " | ";
- break;
- case Instruction::Xor:
- O << " ^ ";
- break;
- default:
- break;
+ default: llvm_unreachable("Unknown binary operator constant cast expr");
+ case Instruction::Add: return MCBinaryExpr::CreateAdd(LHS, RHS, Ctx);
+ case Instruction::Sub: return MCBinaryExpr::CreateSub(LHS, RHS, Ctx);
+ case Instruction::And: return MCBinaryExpr::CreateAnd(LHS, RHS, Ctx);
+ case Instruction::Or: return MCBinaryExpr::CreateOr (LHS, RHS, Ctx);
+ case Instruction::Xor: return MCBinaryExpr::CreateXor(LHS, RHS, Ctx);
}
- O << '(';
- EmitConstantValueOnly(CE->getOperand(1));
- O << ')';
- break;
}
-}
-
-/// printAsCString - Print the specified array as a C compatible string, only if
-/// the predicate isString is true.
-///
-static void printAsCString(formatted_raw_ostream &O, const ConstantArray *CVA,
- unsigned LastElt) {
- assert(CVA->isString() && "Array is not string compatible!");
-
- O << '\"';
- for (unsigned i = 0; i != LastElt; ++i) {
- unsigned char C =
- (unsigned char)cast<ConstantInt>(CVA->getOperand(i))->getZExtValue();
- printStringChar(O, C);
}
- O << '\"';
}
-/// EmitString - Emit a zero-byte-terminated string constant.
-///
-void AsmPrinter::EmitString(const ConstantArray *CVA) const {
- unsigned NumElts = CVA->getNumOperands();
- if (MAI->getAscizDirective() && NumElts &&
- cast<ConstantInt>(CVA->getOperand(NumElts-1))->getZExtValue() == 0) {
- O << MAI->getAscizDirective();
- printAsCString(O, CVA, NumElts-1);
- } else {
- O << MAI->getAsciiDirective();
- printAsCString(O, CVA, NumElts);
+static void EmitGlobalConstantArray(const ConstantArray *CA, unsigned AddrSpace,
+ AsmPrinter &AP) {
+ if (AddrSpace != 0 || !CA->isString()) {
+ // Not a string. Print the values in successive locations
+ for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
+ AP.EmitGlobalConstant(CA->getOperand(i), AddrSpace);
+ return;
}
- O << '\n';
-}
+
+ // Otherwise, it can be emitted as .ascii.
+ SmallVector<char, 128> TmpVec;
+ TmpVec.reserve(CA->getNumOperands());
+ for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
+ TmpVec.push_back(cast<ConstantInt>(CA->getOperand(i))->getZExtValue());
-void AsmPrinter::EmitGlobalConstantArray(const ConstantArray *CVA,
- unsigned AddrSpace) {
- if (CVA->isString()) {
- EmitString(CVA);
- } else { // Not a string. Print the values in successive locations
- for (unsigned i = 0, e = CVA->getNumOperands(); i != e; ++i)
- EmitGlobalConstant(CVA->getOperand(i), AddrSpace);
- }
+ AP.OutStreamer.EmitBytes(StringRef(TmpVec.data(), TmpVec.size()), AddrSpace);
}
-void AsmPrinter::EmitGlobalConstantVector(const ConstantVector *CP) {
- const VectorType *PTy = CP->getType();
-
- for (unsigned I = 0, E = PTy->getNumElements(); I < E; ++I)
- EmitGlobalConstant(CP->getOperand(I));
+static void EmitGlobalConstantVector(const ConstantVector *CV,
+ unsigned AddrSpace, AsmPrinter &AP) {
+ for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i)
+ AP.EmitGlobalConstant(CV->getOperand(i), AddrSpace);
}
-void AsmPrinter::EmitGlobalConstantStruct(const ConstantStruct *CVS,
- unsigned AddrSpace) {
+static void EmitGlobalConstantStruct(const ConstantStruct *CS,
+ unsigned AddrSpace, AsmPrinter &AP) {
// Print the fields in successive locations. Pad to align if needed!
- const TargetData *TD = TM.getTargetData();
- unsigned Size = TD->getTypeAllocSize(CVS->getType());
- const StructLayout *cvsLayout = TD->getStructLayout(CVS->getType());
- uint64_t sizeSoFar = 0;
- for (unsigned i = 0, e = CVS->getNumOperands(); i != e; ++i) {
- const Constant* field = CVS->getOperand(i);
+ const TargetData *TD = AP.TM.getTargetData();
+ unsigned Size = TD->getTypeAllocSize(CS->getType());
+ const StructLayout *Layout = TD->getStructLayout(CS->getType());
+ uint64_t SizeSoFar = 0;
+ for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) {
+ const Constant *Field = CS->getOperand(i);
// Check if padding is needed and insert one or more 0s.
- uint64_t fieldSize = TD->getTypeAllocSize(field->getType());
- uint64_t padSize = ((i == e-1 ? Size : cvsLayout->getElementOffset(i+1))
- - cvsLayout->getElementOffset(i)) - fieldSize;
- sizeSoFar += fieldSize + padSize;
+ uint64_t FieldSize = TD->getTypeAllocSize(Field->getType());
+ uint64_t PadSize = ((i == e-1 ? Size : Layout->getElementOffset(i+1))
+ - Layout->getElementOffset(i)) - FieldSize;
+ SizeSoFar += FieldSize + PadSize;
// Now print the actual field value.
- EmitGlobalConstant(field, AddrSpace);
+ AP.EmitGlobalConstant(Field, AddrSpace);
// Insert padding - this may include padding to increase the size of the
// current field up to the ABI size (if the struct is not packed) as well
// as padding to ensure that the next field starts at the right offset.
- EmitZeros(padSize, AddrSpace);
+ AP.OutStreamer.EmitZeros(PadSize, AddrSpace);
}
- assert(sizeSoFar == cvsLayout->getSizeInBytes() &&
+ assert(SizeSoFar == Layout->getSizeInBytes() &&
"Layout of constant struct may be incorrect!");
}
-void AsmPrinter::EmitGlobalConstantFP(const ConstantFP *CFP,
- unsigned AddrSpace) {
+static void EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
+ AsmPrinter &AP) {
// FP Constants are printed as integer constants to avoid losing
- // precision...
- LLVMContext &Context = CFP->getContext();
- const TargetData *TD = TM.getTargetData();
+ // precision.
if (CFP->getType()->isDoubleTy()) {
- double Val = CFP->getValueAPF().convertToDouble(); // for comment only
- uint64_t i = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
- if (MAI->getData64bitsDirective(AddrSpace)) {
- O << MAI->getData64bitsDirective(AddrSpace) << i;
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << " double " << Val;
- }
- O << '\n';
- } else if (TD->isBigEndian()) {
- O << MAI->getData32bitsDirective(AddrSpace) << unsigned(i >> 32);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " most significant word of double " << Val;
- }
- O << '\n';
- O << MAI->getData32bitsDirective(AddrSpace) << unsigned(i);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " least significant word of double " << Val;
- }
- O << '\n';
- } else {
- O << MAI->getData32bitsDirective(AddrSpace) << unsigned(i);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " least significant word of double " << Val;
- }
- O << '\n';
- O << MAI->getData32bitsDirective(AddrSpace) << unsigned(i >> 32);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " most significant word of double " << Val;
- }
- O << '\n';
+ if (AP.VerboseAsm) {
+ double Val = CFP->getValueAPF().convertToDouble();
+ AP.OutStreamer.GetCommentOS() << "double " << Val << '\n';
}
+
+ uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
+ AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace);
return;
}
if (CFP->getType()->isFloatTy()) {
- float Val = CFP->getValueAPF().convertToFloat(); // for comment only
- O << MAI->getData32bitsDirective(AddrSpace)
- << CFP->getValueAPF().bitcastToAPInt().getZExtValue();
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << " float " << Val;
+ if (AP.VerboseAsm) {
+ float Val = CFP->getValueAPF().convertToFloat();
+ AP.OutStreamer.GetCommentOS() << "float " << Val << '\n';
}
- O << '\n';
+ uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
+ AP.OutStreamer.EmitIntValue(Val, 4, AddrSpace);
return;
}
if (CFP->getType()->isX86_FP80Ty()) {
// all long double variants are printed as hex
// api needed to prevent premature destruction
- APInt api = CFP->getValueAPF().bitcastToAPInt();
- const uint64_t *p = api.getRawData();
- // Convert to double so we can print the approximate val as a comment.
- APFloat DoubleVal = CFP->getValueAPF();
- bool ignored;
- DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven,
- &ignored);
- if (TD->isBigEndian()) {
- O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[1]);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " most significant halfword of x86_fp80 ~"
- << DoubleVal.convertToDouble();
- }
- O << '\n';
- O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 48);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << " next halfword";
- }
- O << '\n';
- O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 32);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << " next halfword";
- }
- O << '\n';
- O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 16);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << " next halfword";
- }
- O << '\n';
- O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0]);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " least significant halfword";
- }
- O << '\n';
- } else {
- O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0]);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " least significant halfword of x86_fp80 ~"
- << DoubleVal.convertToDouble();
- }
- O << '\n';
- O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 16);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " next halfword";
- }
- O << '\n';
- O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 32);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " next halfword";
- }
- O << '\n';
- O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 48);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " next halfword";
- }
- O << '\n';
- O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[1]);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " most significant halfword";
- }
- O << '\n';
+ APInt API = CFP->getValueAPF().bitcastToAPInt();
+ const uint64_t *p = API.getRawData();
+ if (AP.VerboseAsm) {
+ // Convert to double so we can print the approximate val as a comment.
+ APFloat DoubleVal = CFP->getValueAPF();
+ bool ignored;
+ DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven,
+ &ignored);
+ AP.OutStreamer.GetCommentOS() << "x86_fp80 ~= "
+ << DoubleVal.convertToDouble() << '\n';
}
- EmitZeros(TD->getTypeAllocSize(Type::getX86_FP80Ty(Context)) -
- TD->getTypeStoreSize(Type::getX86_FP80Ty(Context)), AddrSpace);
+
+ if (AP.TM.getTargetData()->isBigEndian()) {
+ AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace);
+ AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace);
+ } else {
+ AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace);
+ AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace);
+ }
+
+ // Emit the tail padding for the long double.
+ const TargetData &TD = *AP.TM.getTargetData();
+ AP.OutStreamer.EmitZeros(TD.getTypeAllocSize(CFP->getType()) -
+ TD.getTypeStoreSize(CFP->getType()), AddrSpace);
return;
}
- if (CFP->getType()->isPPC_FP128Ty()) {
- // all long double variants are printed as hex
- // api needed to prevent premature destruction
- APInt api = CFP->getValueAPF().bitcastToAPInt();
- const uint64_t *p = api.getRawData();
- if (TD->isBigEndian()) {
- O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0] >> 32);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " most significant word of ppc_fp128";
- }
- O << '\n';
- O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0]);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " next word";
- }
- O << '\n';
- O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1] >> 32);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " next word";
- }
- O << '\n';
- O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1]);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " least significant word";
- }
- O << '\n';
- } else {
- O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1]);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " least significant word of ppc_fp128";
- }
- O << '\n';
- O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1] >> 32);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " next word";
- }
- O << '\n';
- O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0]);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " next word";
- }
- O << '\n';
- O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0] >> 32);
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << " most significant word";
- }
- O << '\n';
- }
- return;
- } else llvm_unreachable("Floating point constant type not handled");
+ assert(CFP->getType()->isPPC_FP128Ty() &&
+ "Floating point constant type not handled");
+ // All long double variants are printed as hex api needed to prevent
+ // premature destruction.
+ APInt API = CFP->getValueAPF().bitcastToAPInt();
+ const uint64_t *p = API.getRawData();
+ if (AP.TM.getTargetData()->isBigEndian()) {
+ AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace);
+ AP.OutStreamer.EmitIntValue(p[1], 8, AddrSpace);
+ } else {
+ AP.OutStreamer.EmitIntValue(p[1], 8, AddrSpace);
+ AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace);
+ }
}
-void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI,
- unsigned AddrSpace) {
- const TargetData *TD = TM.getTargetData();
+static void EmitGlobalConstantLargeInt(const ConstantInt *CI,
+ unsigned AddrSpace, AsmPrinter &AP) {
+ const TargetData *TD = AP.TM.getTargetData();
unsigned BitWidth = CI->getBitWidth();
assert((BitWidth & 63) == 0 && "only support multiples of 64-bits");
@@ -1253,100 +1003,58 @@ void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI,
// quantities at a time.
const uint64_t *RawData = CI->getValue().getRawData();
for (unsigned i = 0, e = BitWidth / 64; i != e; ++i) {
- uint64_t Val;
- if (TD->isBigEndian())
- Val = RawData[e - i - 1];
- else
- Val = RawData[i];
-
- if (MAI->getData64bitsDirective(AddrSpace)) {
- O << MAI->getData64bitsDirective(AddrSpace) << Val << '\n';
- continue;
- }
-
- // Emit two 32-bit chunks, order depends on endianness.
- unsigned FirstChunk = unsigned(Val), SecondChunk = unsigned(Val >> 32);
- const char *FirstName = " least", *SecondName = " most";
- if (TD->isBigEndian()) {
- std::swap(FirstChunk, SecondChunk);
- std::swap(FirstName, SecondName);
- }
-
- O << MAI->getData32bitsDirective(AddrSpace) << FirstChunk;
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << FirstName << " significant half of i64 " << Val;
- }
- O << '\n';
-
- O << MAI->getData32bitsDirective(AddrSpace) << SecondChunk;
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString()
- << SecondName << " significant half of i64 " << Val;
- }
- O << '\n';
+ uint64_t Val = TD->isBigEndian() ? RawData[e - i - 1] : RawData[i];
+ AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace);
}
}
/// EmitGlobalConstant - Print a general LLVM constant to the .s file.
void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) {
- const TargetData *TD = TM.getTargetData();
- const Type *type = CV->getType();
- unsigned Size = TD->getTypeAllocSize(type);
-
- if (CV->isNullValue() || isa<UndefValue>(CV)) {
- EmitZeros(Size, AddrSpace);
- return;
- }
-
- if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
- EmitGlobalConstantArray(CVA , AddrSpace);
- return;
- }
-
- if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) {
- EmitGlobalConstantStruct(CVS, AddrSpace);
- return;
+ if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV)) {
+ uint64_t Size = TM.getTargetData()->getTypeAllocSize(CV->getType());
+ return OutStreamer.EmitZeros(Size, AddrSpace);
}
- if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
- EmitGlobalConstantFP(CFP, AddrSpace);
- return;
- }
-
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
- // If we can directly emit an 8-byte constant, do it.
- if (Size == 8)
- if (const char *Data64Dir = MAI->getData64bitsDirective(AddrSpace)) {
- O << Data64Dir << CI->getZExtValue() << '\n';
- return;
- }
-
- // Small integers are handled below; large integers are handled here.
- if (Size > 4) {
- EmitGlobalConstantLargeInt(CI, AddrSpace);
+ unsigned Size = TM.getTargetData()->getTypeAllocSize(CV->getType());
+ switch (Size) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ if (VerboseAsm)
+ OutStreamer.GetCommentOS() << format("0x%llx\n", CI->getZExtValue());
+ OutStreamer.EmitIntValue(CI->getZExtValue(), Size, AddrSpace);
+ return;
+ default:
+ EmitGlobalConstantLargeInt(CI, AddrSpace, *this);
return;
}
}
- if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
- EmitGlobalConstantVector(CP);
- return;
- }
+ if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV))
+ return EmitGlobalConstantArray(CVA, AddrSpace, *this);
+
+ if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))
+ return EmitGlobalConstantStruct(CVS, AddrSpace, *this);
- printDataDirective(type, AddrSpace);
- EmitConstantValueOnly(CV);
- if (VerboseAsm) {
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
- SmallString<40> S;
- CI->getValue().toStringUnsigned(S, 16);
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << " 0x" << S.str();
- }
+ if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV))
+ return EmitGlobalConstantFP(CFP, AddrSpace, *this);
+
+ if (const ConstantVector *V = dyn_cast<ConstantVector>(CV))
+ return EmitGlobalConstantVector(V, AddrSpace, *this);
+
+ if (isa<ConstantPointerNull>(CV)) {
+ unsigned Size = TM.getTargetData()->getTypeAllocSize(CV->getType());
+ OutStreamer.EmitIntValue(0, Size, AddrSpace);
+ return;
}
- O << '\n';
+
+ // Otherwise, it must be a ConstantExpr. Lower it to an MCExpr, then emit it
+ // thread the streamer with EmitValue.
+ OutStreamer.EmitValue(LowerConstant(CV, *this),
+ TM.getTargetData()->getTypeAllocSize(CV->getType()),
+ AddrSpace);
}
void AsmPrinter::EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
@@ -1397,22 +1105,21 @@ void AsmPrinter::processDebugLoc(const MachineInstr *MI,
DebugLoc DL = MI->getDebugLoc();
if (DL.isUnknown())
return;
- DebugLocTuple CurDLT = MF->getDebugLocTuple(DL);
- if (CurDLT.Scope == 0)
+ DILocation CurDLT = MF->getDILocation(DL);
+ if (CurDLT.getScope().isNull())
return;
- if (BeforePrintingInsn) {
- if (CurDLT != PrevDLT) {
- unsigned L = DW->RecordSourceLine(CurDLT.Line, CurDLT.Col,
- CurDLT.Scope);
- printLabel(L);
- O << '\n';
- DW->BeginScope(MI, L);
- PrevDLT = CurDLT;
- }
- } else {
+ if (!BeforePrintingInsn) {
// After printing instruction
DW->EndScope(MI);
+ } else if (CurDLT.getNode() != PrevDLT) {
+ unsigned L = DW->RecordSourceLine(CurDLT.getLineNumber(),
+ CurDLT.getColumnNumber(),
+ CurDLT.getScope().getNode());
+ printLabel(L);
+ O << '\n';
+ DW->BeginScope(MI, L);
+ PrevDLT = CurDLT.getNode();
}
}
@@ -1587,9 +1294,8 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const {
unsigned OpFlags = MI->getOperand(OpNo).getImm();
++OpNo; // Skip over the ID number.
- if (Modifier[0]=='l') // labels are target independent
- GetMBBSymbol(MI->getOperand(OpNo).getMBB()
- ->getNumber())->print(O, MAI);
+ if (Modifier[0] == 'l') // labels are target independent
+ O << *GetMBBSymbol(MI->getOperand(OpNo).getMBB()->getNumber());
else {
AsmPrinter *AP = const_cast<AsmPrinter*>(this);
if ((OpFlags & 7) == 4) {
@@ -1604,8 +1310,7 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const {
if (Error) {
std::string msg;
raw_string_ostream Msg(msg);
- Msg << "Invalid operand found in inline asm: '"
- << AsmStr << "'\n";
+ Msg << "Invalid operand found in inline asm: '" << AsmStr << "'\n";
MI->print(Msg);
llvm_report_error(Msg.str());
}
@@ -1694,10 +1399,121 @@ MCSymbol *AsmPrinter::GetMBBSymbol(unsigned MBBID) const {
SmallString<60> Name;
raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "BB"
<< getFunctionNumber() << '_' << MBBID;
-
return OutContext.GetOrCreateSymbol(Name.str());
}
+/// GetCPISymbol - Return the symbol for the specified constant pool entry.
+MCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const {
+ SmallString<60> Name;
+ raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "CPI"
+ << getFunctionNumber() << '_' << CPID;
+ return OutContext.GetOrCreateSymbol(Name.str());
+}
+
+/// GetJTISymbol - Return the symbol for the specified jump table entry.
+MCSymbol *AsmPrinter::GetJTISymbol(unsigned JTID, bool isLinkerPrivate) const {
+ const char *Prefix = isLinkerPrivate ? MAI->getLinkerPrivateGlobalPrefix() :
+ MAI->getPrivateGlobalPrefix();
+ SmallString<60> Name;
+ raw_svector_ostream(Name) << Prefix << "JTI" << getFunctionNumber() << '_'
+ << JTID;
+ return OutContext.GetOrCreateSymbol(Name.str());
+}
+
+/// GetGlobalValueSymbol - Return the MCSymbol for the specified global
+/// value.
+MCSymbol *AsmPrinter::GetGlobalValueSymbol(const GlobalValue *GV) const {
+ SmallString<60> NameStr;
+ Mang->getNameWithPrefix(NameStr, GV, false);
+ return OutContext.GetOrCreateSymbol(NameStr.str());
+}
+
+/// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with
+/// global value name as its base, with the specified suffix, and where the
+/// symbol is forced to have private linkage if ForcePrivate is true.
+MCSymbol *AsmPrinter::GetSymbolWithGlobalValueBase(const GlobalValue *GV,
+ StringRef Suffix,
+ bool ForcePrivate) const {
+ SmallString<60> NameStr;
+ Mang->getNameWithPrefix(NameStr, GV, ForcePrivate);
+ NameStr.append(Suffix.begin(), Suffix.end());
+ return OutContext.GetOrCreateSymbol(NameStr.str());
+}
+
+/// GetExternalSymbolSymbol - Return the MCSymbol for the specified
+/// ExternalSymbol.
+MCSymbol *AsmPrinter::GetExternalSymbolSymbol(StringRef Sym) const {
+ SmallString<60> NameStr;
+ Mang->getNameWithPrefix(NameStr, Sym);
+ return OutContext.GetOrCreateSymbol(NameStr.str());
+}
+
+
+
+/// PrintParentLoopComment - Print comments about parent loops of this one.
+static void PrintParentLoopComment(raw_ostream &OS, const MachineLoop *Loop,
+ unsigned FunctionNumber) {
+ if (Loop == 0) return;
+ PrintParentLoopComment(OS, Loop->getParentLoop(), FunctionNumber);
+ OS.indent(Loop->getLoopDepth()*2)
+ << "Parent Loop BB" << FunctionNumber << "_"
+ << Loop->getHeader()->getNumber()
+ << " Depth=" << Loop->getLoopDepth() << '\n';
+}
+
+
+/// PrintChildLoopComment - Print comments about child loops within
+/// the loop for this basic block, with nesting.
+static void PrintChildLoopComment(raw_ostream &OS, const MachineLoop *Loop,
+ unsigned FunctionNumber) {
+ // Add child loop information
+ for (MachineLoop::iterator CL = Loop->begin(), E = Loop->end();CL != E; ++CL){
+ OS.indent((*CL)->getLoopDepth()*2)
+ << "Child Loop BB" << FunctionNumber << "_"
+ << (*CL)->getHeader()->getNumber() << " Depth " << (*CL)->getLoopDepth()
+ << '\n';
+ PrintChildLoopComment(OS, *CL, FunctionNumber);
+ }
+}
+
+/// EmitComments - Pretty-print comments for basic blocks.
+static void PrintBasicBlockLoopComments(const MachineBasicBlock &MBB,
+ const MachineLoopInfo *LI,
+ const AsmPrinter &AP) {
+ // Add loop depth information
+ const MachineLoop *Loop = LI->getLoopFor(&MBB);
+ if (Loop == 0) return;
+
+ MachineBasicBlock *Header = Loop->getHeader();
+ assert(Header && "No header for loop");
+
+ // If this block is not a loop header, just print out what is the loop header
+ // and return.
+ if (Header != &MBB) {
+ AP.OutStreamer.AddComment(" in Loop: Header=BB" +
+ Twine(AP.getFunctionNumber())+"_" +
+ Twine(Loop->getHeader()->getNumber())+
+ " Depth="+Twine(Loop->getLoopDepth()));
+ return;
+ }
+
+ // Otherwise, it is a loop header. Print out information about child and
+ // parent loops.
+ raw_ostream &OS = AP.OutStreamer.GetCommentOS();
+
+ PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber());
+
+ OS << "=>";
+ OS.indent(Loop->getLoopDepth()*2-2);
+
+ OS << "This ";
+ if (Loop->empty())
+ OS << "Inner ";
+ OS << "Loop Header: Depth=" + Twine(Loop->getLoopDepth()) << '\n';
+
+ PrintChildLoopComment(OS, Loop, AP.getFunctionNumber());
+}
+
/// EmitBasicBlockStart - This method prints the label for the specified
/// MachineBasicBlock, an alignment (if present) and a comment describing
@@ -1713,38 +1529,33 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const {
// forward references to labels without knowing what their numbers
// will be.
if (MBB->hasAddressTaken()) {
- GetBlockAddressSymbol(MBB->getBasicBlock()->getParent(),
- MBB->getBasicBlock())->print(O, MAI);
- O << ':';
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << " Address Taken";
- }
- O << '\n';
+ const BasicBlock *BB = MBB->getBasicBlock();
+ if (VerboseAsm)
+ OutStreamer.AddComment("Address Taken");
+ OutStreamer.EmitLabel(GetBlockAddressSymbol(BB->getParent(), BB));
}
// Print the main label for the block.
if (MBB->pred_empty() || MBB->isOnlyReachableByFallthrough()) {
- if (VerboseAsm)
+ if (VerboseAsm) {
+ // NOTE: Want this comment at start of line.
O << MAI->getCommentString() << " BB#" << MBB->getNumber() << ':';
+ if (const BasicBlock *BB = MBB->getBasicBlock())
+ if (BB->hasName())
+ OutStreamer.AddComment("%" + BB->getName());
+
+ PrintBasicBlockLoopComments(*MBB, LI, *this);
+ OutStreamer.AddBlankLine();
+ }
} else {
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
- O << ':';
- if (!VerboseAsm)
- O << '\n';
- }
-
- // Print some comments to accompany the label.
- if (VerboseAsm) {
- if (const BasicBlock *BB = MBB->getBasicBlock())
- if (BB->hasName()) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, BB, /*PrintType=*/false);
- }
+ if (VerboseAsm) {
+ if (const BasicBlock *BB = MBB->getBasicBlock())
+ if (BB->hasName())
+ OutStreamer.AddComment("%" + BB->getName());
+ PrintBasicBlockLoopComments(*MBB, LI, *this);
+ }
- EmitComments(*MBB);
- O << '\n';
+ OutStreamer.EmitLabel(GetMBBSymbol(MBB->getNumber()));
}
}
@@ -1756,10 +1567,9 @@ void AsmPrinter::printPICJumpTableSetLabel(unsigned uid,
return;
O << MAI->getSetDirective() << ' ' << MAI->getPrivateGlobalPrefix()
- << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ',';
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
- O << '-' << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
- << '_' << uid << '\n';
+ << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ','
+ << *GetMBBSymbol(MBB->getNumber())
+ << '-' << *GetJTISymbol(uid) << '\n';
}
void AsmPrinter::printPICJumpTableSetLabel(unsigned uid, unsigned uid2,
@@ -1769,64 +1579,27 @@ void AsmPrinter::printPICJumpTableSetLabel(unsigned uid, unsigned uid2,
O << MAI->getSetDirective() << ' ' << MAI->getPrivateGlobalPrefix()
<< getFunctionNumber() << '_' << uid << '_' << uid2
- << "_set_" << MBB->getNumber() << ',';
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
- O << '-' << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
+ << "_set_" << MBB->getNumber() << ','
+ << *GetMBBSymbol(MBB->getNumber())
+ << '-' << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
<< '_' << uid << '_' << uid2 << '\n';
}
-/// printDataDirective - This method prints the asm directive for the
-/// specified type.
-void AsmPrinter::printDataDirective(const Type *type, unsigned AddrSpace) {
- const TargetData *TD = TM.getTargetData();
- switch (type->getTypeID()) {
- case Type::FloatTyID: case Type::DoubleTyID:
- case Type::X86_FP80TyID: case Type::FP128TyID: case Type::PPC_FP128TyID:
- assert(0 && "Should have already output floating point constant.");
- default:
- assert(0 && "Can't handle printing this type of thing");
- case Type::IntegerTyID: {
- unsigned BitWidth = cast<IntegerType>(type)->getBitWidth();
- if (BitWidth <= 8)
- O << MAI->getData8bitsDirective(AddrSpace);
- else if (BitWidth <= 16)
- O << MAI->getData16bitsDirective(AddrSpace);
- else if (BitWidth <= 32)
- O << MAI->getData32bitsDirective(AddrSpace);
- else if (BitWidth <= 64) {
- assert(MAI->getData64bitsDirective(AddrSpace) &&
- "Target cannot handle 64-bit constant exprs!");
- O << MAI->getData64bitsDirective(AddrSpace);
- } else {
- llvm_unreachable("Target cannot handle given data directive width!");
- }
+void AsmPrinter::printVisibility(MCSymbol *Sym, unsigned Visibility) const {
+ MCSymbolAttr Attr = MCSA_Invalid;
+
+ switch (Visibility) {
+ default: break;
+ case GlobalValue::HiddenVisibility:
+ Attr = MAI->getHiddenVisibilityAttr();
break;
- }
- case Type::PointerTyID:
- if (TD->getPointerSize() == 8) {
- assert(MAI->getData64bitsDirective(AddrSpace) &&
- "Target cannot handle 64-bit pointer exprs!");
- O << MAI->getData64bitsDirective(AddrSpace);
- } else if (TD->getPointerSize() == 2) {
- O << MAI->getData16bitsDirective(AddrSpace);
- } else if (TD->getPointerSize() == 1) {
- O << MAI->getData8bitsDirective(AddrSpace);
- } else {
- O << MAI->getData32bitsDirective(AddrSpace);
- }
+ case GlobalValue::ProtectedVisibility:
+ Attr = MAI->getProtectedVisibilityAttr();
break;
}
-}
-void AsmPrinter::printVisibility(const std::string& Name,
- unsigned Visibility) const {
- if (Visibility == GlobalValue::HiddenVisibility) {
- if (const char *Directive = MAI->getHiddenDirective())
- O << Directive << Name << '\n';
- } else if (Visibility == GlobalValue::ProtectedVisibility) {
- if (const char *Directive = MAI->getProtectedDirective())
- O << Directive << Name << '\n';
- }
+ if (Attr != MCSA_Invalid)
+ OutStreamer.EmitSymbolAttribute(Sym, Attr);
}
void AsmPrinter::printOffset(int64_t Offset) const {
@@ -1856,8 +1629,8 @@ GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) {
return GMP;
}
- errs() << "no GCMetadataPrinter registered for GC: " << Name << "\n";
- llvm_unreachable(0);
+ llvm_report_error("no GCMetadataPrinter registered for GC: " + Twine(Name));
+ return 0;
}
/// EmitComments - Pretty-print comments for instructions
@@ -1868,20 +1641,20 @@ void AsmPrinter::EmitComments(const MachineInstr &MI) const {
bool Newline = false;
if (!MI.getDebugLoc().isUnknown()) {
- DebugLocTuple DLT = MF->getDebugLocTuple(MI.getDebugLoc());
+ DILocation DLT = MF->getDILocation(MI.getDebugLoc());
// Print source line info.
O.PadToColumn(MAI->getCommentColumn());
O << MAI->getCommentString() << ' ';
- DIScope Scope(DLT.Scope);
+ DIScope Scope = DLT.getScope();
// Omit the directory, because it's likely to be long and uninteresting.
if (!Scope.isNull())
O << Scope.getFilename();
else
O << "<unknown>";
- O << ':' << DLT.Line;
- if (DLT.Col != 0)
- O << ':' << DLT.Col;
+ O << ':' << DLT.getLineNumber();
+ if (DLT.getColumnNumber() != 0)
+ O << ':' << DLT.getColumnNumber();
Newline = true;
}
@@ -1943,80 +1716,3 @@ void AsmPrinter::EmitComments(const MachineInstr &MI) const {
}
}
-/// PrintChildLoopComment - Print comments about child loops within
-/// the loop for this basic block, with nesting.
-///
-static void PrintChildLoopComment(formatted_raw_ostream &O,
- const MachineLoop *loop,
- const MCAsmInfo *MAI,
- int FunctionNumber) {
- // Add child loop information
- for(MachineLoop::iterator cl = loop->begin(),
- clend = loop->end();
- cl != clend;
- ++cl) {
- MachineBasicBlock *Header = (*cl)->getHeader();
- assert(Header && "No header for loop");
-
- O << '\n';
- O.PadToColumn(MAI->getCommentColumn());
-
- O << MAI->getCommentString();
- O.indent(((*cl)->getLoopDepth()-1)*2)
- << " Child Loop BB" << FunctionNumber << "_"
- << Header->getNumber() << " Depth " << (*cl)->getLoopDepth();
-
- PrintChildLoopComment(O, *cl, MAI, FunctionNumber);
- }
-}
-
-/// EmitComments - Pretty-print comments for basic blocks
-void AsmPrinter::EmitComments(const MachineBasicBlock &MBB) const {
- if (VerboseAsm) {
- // Add loop depth information
- const MachineLoop *loop = LI->getLoopFor(&MBB);
-
- if (loop) {
- // Print a newline after bb# annotation.
- O << "\n";
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << " Loop Depth " << loop->getLoopDepth()
- << '\n';
-
- O.PadToColumn(MAI->getCommentColumn());
-
- MachineBasicBlock *Header = loop->getHeader();
- assert(Header && "No header for loop");
-
- if (Header == &MBB) {
- O << MAI->getCommentString() << " Loop Header";
- PrintChildLoopComment(O, loop, MAI, getFunctionNumber());
- }
- else {
- O << MAI->getCommentString() << " Loop Header is BB"
- << getFunctionNumber() << "_" << loop->getHeader()->getNumber();
- }
-
- if (loop->empty()) {
- O << '\n';
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << " Inner Loop";
- }
-
- // Add parent loop information
- for (const MachineLoop *CurLoop = loop->getParentLoop();
- CurLoop;
- CurLoop = CurLoop->getParentLoop()) {
- MachineBasicBlock *Header = CurLoop->getHeader();
- assert(Header && "No header for loop");
-
- O << '\n';
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString();
- O.indent((CurLoop->getLoopDepth()-1)*2)
- << " Inside Loop BB" << getFunctionNumber() << "_"
- << Header->getNumber() << " Depth " << CurLoop->getLoopDepth();
- }
- }
- }
-}
diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp
index b85e11a..349e0ac 100644
--- a/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -13,12 +13,16 @@
#include "DIE.h"
#include "DwarfPrinter.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/FormattedStream.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -49,31 +53,33 @@ void DIEAbbrev::Profile(FoldingSetNodeID &ID) const {
/// Emit - Print the abbreviation using the specified asm printer.
///
-void DIEAbbrev::Emit(const AsmPrinter *Asm) const {
+void DIEAbbrev::Emit(const DwarfPrinter *DP) const {
// Emit its Dwarf tag type.
- Asm->EmitULEB128Bytes(Tag);
- Asm->EOL(dwarf::TagString(Tag));
+ // FIXME: Doing work even in non-asm-verbose runs.
+ DP->EmitULEB128(Tag, dwarf::TagString(Tag));
// Emit whether it has children DIEs.
- Asm->EmitULEB128Bytes(ChildrenFlag);
- Asm->EOL(dwarf::ChildrenString(ChildrenFlag));
+ // FIXME: Doing work even in non-asm-verbose runs.
+ DP->EmitULEB128(ChildrenFlag, dwarf::ChildrenString(ChildrenFlag));
// For each attribute description.
for (unsigned i = 0, N = Data.size(); i < N; ++i) {
const DIEAbbrevData &AttrData = Data[i];
// Emit attribute type.
- Asm->EmitULEB128Bytes(AttrData.getAttribute());
- Asm->EOL(dwarf::AttributeString(AttrData.getAttribute()));
+ // FIXME: Doing work even in non-asm-verbose runs.
+ DP->EmitULEB128(AttrData.getAttribute(),
+ dwarf::AttributeString(AttrData.getAttribute()));
// Emit form type.
- Asm->EmitULEB128Bytes(AttrData.getForm());
- Asm->EOL(dwarf::FormEncodingString(AttrData.getForm()));
+ // FIXME: Doing work even in non-asm-verbose runs.
+ DP->EmitULEB128(AttrData.getForm(),
+ dwarf::FormEncodingString(AttrData.getForm()));
}
// Mark end of abbreviation.
- Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(1)");
- Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(2)");
+ DP->EmitULEB128(0, "EOM(1)");
+ DP->EmitULEB128(0, "EOM(2)");
}
#ifndef NDEBUG
@@ -182,22 +188,24 @@ void DIEValue::dump() {
/// EmitValue - Emit integer of appropriate size.
///
-void DIEInteger::EmitValue(Dwarf *D, unsigned Form) const {
+void DIEInteger::EmitValue(DwarfPrinter *D, unsigned Form) const {
const AsmPrinter *Asm = D->getAsm();
+ unsigned Size = ~0U;
switch (Form) {
case dwarf::DW_FORM_flag: // Fall thru
case dwarf::DW_FORM_ref1: // Fall thru
- case dwarf::DW_FORM_data1: Asm->EmitInt8(Integer); break;
+ case dwarf::DW_FORM_data1: Size = 1; break;
case dwarf::DW_FORM_ref2: // Fall thru
- case dwarf::DW_FORM_data2: Asm->EmitInt16(Integer); break;
+ case dwarf::DW_FORM_data2: Size = 2; break;
case dwarf::DW_FORM_ref4: // Fall thru
- case dwarf::DW_FORM_data4: Asm->EmitInt32(Integer); break;
+ case dwarf::DW_FORM_data4: Size = 4; break;
case dwarf::DW_FORM_ref8: // Fall thru
- case dwarf::DW_FORM_data8: Asm->EmitInt64(Integer); break;
- case dwarf::DW_FORM_udata: Asm->EmitULEB128Bytes(Integer); break;
- case dwarf::DW_FORM_sdata: Asm->EmitSLEB128Bytes(Integer); break;
+ case dwarf::DW_FORM_data8: Size = 8; break;
+ case dwarf::DW_FORM_udata: D->EmitULEB128(Integer); return;
+ case dwarf::DW_FORM_sdata: D->EmitSLEB128(Integer, ""); return;
default: llvm_unreachable("DIE Value form not supported yet");
}
+ Asm->OutStreamer.EmitIntValue(Integer, Size, 0/*addrspace*/);
}
/// SizeOf - Determine size of integer value in bytes.
@@ -233,8 +241,10 @@ void DIEInteger::print(raw_ostream &O) {
/// EmitValue - Emit string value.
///
-void DIEString::EmitValue(Dwarf *D, unsigned Form) const {
- D->getAsm()->EmitString(Str);
+void DIEString::EmitValue(DwarfPrinter *D, unsigned Form) const {
+ D->getAsm()->OutStreamer.EmitBytes(Str, /*addrspace*/0);
+ // Emit nul terminator.
+ D->getAsm()->OutStreamer.EmitIntValue(0, 1, /*addrspace*/0);
}
#ifndef NDEBUG
@@ -249,7 +259,7 @@ void DIEString::print(raw_ostream &O) {
/// EmitValue - Emit label value.
///
-void DIEDwarfLabel::EmitValue(Dwarf *D, unsigned Form) const {
+void DIEDwarfLabel::EmitValue(DwarfPrinter *D, unsigned Form) const {
bool IsSmall = Form == dwarf::DW_FORM_data4;
D->EmitReference(Label, false, IsSmall);
}
@@ -274,9 +284,9 @@ void DIEDwarfLabel::print(raw_ostream &O) {
/// EmitValue - Emit label value.
///
-void DIEObjectLabel::EmitValue(Dwarf *D, unsigned Form) const {
+void DIEObjectLabel::EmitValue(DwarfPrinter *D, unsigned Form) const {
bool IsSmall = Form == dwarf::DW_FORM_data4;
- D->EmitReference(Label, false, IsSmall);
+ D->EmitReference(Sym, false, IsSmall);
}
/// SizeOf - Determine size of label value in bytes.
@@ -288,7 +298,7 @@ unsigned DIEObjectLabel::SizeOf(const TargetData *TD, unsigned Form) const {
#ifndef NDEBUG
void DIEObjectLabel::print(raw_ostream &O) {
- O << "Obj: " << Label;
+ O << "Obj: " << Sym->getName();
}
#endif
@@ -298,7 +308,7 @@ void DIEObjectLabel::print(raw_ostream &O) {
/// EmitValue - Emit delta value.
///
-void DIESectionOffset::EmitValue(Dwarf *D, unsigned Form) const {
+void DIESectionOffset::EmitValue(DwarfPrinter *D, unsigned Form) const {
bool IsSmall = Form == dwarf::DW_FORM_data4;
D->EmitSectionOffset(Label.getTag(), Section.getTag(),
Label.getNumber(), Section.getNumber(),
@@ -328,7 +338,7 @@ void DIESectionOffset::print(raw_ostream &O) {
/// EmitValue - Emit delta value.
///
-void DIEDelta::EmitValue(Dwarf *D, unsigned Form) const {
+void DIEDelta::EmitValue(DwarfPrinter *D, unsigned Form) const {
bool IsSmall = Form == dwarf::DW_FORM_data4;
D->EmitDifference(LabelHi, LabelLo, IsSmall);
}
@@ -355,7 +365,7 @@ void DIEDelta::print(raw_ostream &O) {
/// EmitValue - Emit debug information entry offset.
///
-void DIEEntry::EmitValue(Dwarf *D, unsigned Form) const {
+void DIEEntry::EmitValue(DwarfPrinter *D, unsigned Form) const {
D->getAsm()->EmitInt32(Entry->getOffset());
}
@@ -383,19 +393,19 @@ unsigned DIEBlock::ComputeSize(const TargetData *TD) {
/// EmitValue - Emit block data.
///
-void DIEBlock::EmitValue(Dwarf *D, unsigned Form) const {
+void DIEBlock::EmitValue(DwarfPrinter *D, unsigned Form) const {
const AsmPrinter *Asm = D->getAsm();
switch (Form) {
case dwarf::DW_FORM_block1: Asm->EmitInt8(Size); break;
case dwarf::DW_FORM_block2: Asm->EmitInt16(Size); break;
case dwarf::DW_FORM_block4: Asm->EmitInt32(Size); break;
- case dwarf::DW_FORM_block: Asm->EmitULEB128Bytes(Size); break;
+ case dwarf::DW_FORM_block: D->EmitULEB128(Size); break;
default: llvm_unreachable("Improper form for block"); break;
}
const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
for (unsigned i = 0, N = Values.size(); i < N; ++i) {
- Asm->EOL();
+ Asm->O << '\n';
Values[i]->EmitValue(D, AbbrevData[i].getForm());
}
}
diff --git a/lib/CodeGen/AsmPrinter/DIE.h b/lib/CodeGen/AsmPrinter/DIE.h
index a6dc9b6..af90289 100644
--- a/lib/CodeGen/AsmPrinter/DIE.h
+++ b/lib/CodeGen/AsmPrinter/DIE.h
@@ -23,8 +23,9 @@
namespace llvm {
class AsmPrinter;
- class Dwarf;
+ class DwarfPrinter;
class TargetData;
+ class MCSymbol;
//===--------------------------------------------------------------------===//
/// DIEAbbrevData - Dwarf abbreviation data, describes the one attribute of a
@@ -100,7 +101,7 @@ namespace llvm {
/// Emit - Print the abbreviation using the specified asm printer.
///
- void Emit(const AsmPrinter *Asm) const;
+ void Emit(const DwarfPrinter *DP) const;
#ifndef NDEBUG
void print(raw_ostream &O);
@@ -221,7 +222,7 @@ namespace llvm {
/// EmitValue - Emit value via the Dwarf writer.
///
- virtual void EmitValue(Dwarf *D, unsigned Form) const = 0;
+ virtual void EmitValue(DwarfPrinter *D, unsigned Form) const = 0;
/// SizeOf - Return the size of a value in bytes.
///
@@ -261,7 +262,7 @@ namespace llvm {
/// EmitValue - Emit integer of appropriate size.
///
- virtual void EmitValue(Dwarf *D, unsigned Form) const;
+ virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
/// SizeOf - Determine size of integer value in bytes.
///
@@ -287,7 +288,7 @@ namespace llvm {
/// EmitValue - Emit string value.
///
- virtual void EmitValue(Dwarf *D, unsigned Form) const;
+ virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
/// SizeOf - Determine size of string value in bytes.
///
@@ -314,7 +315,7 @@ namespace llvm {
/// EmitValue - Emit label value.
///
- virtual void EmitValue(Dwarf *D, unsigned Form) const;
+ virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
/// SizeOf - Determine size of label value in bytes.
///
@@ -333,14 +334,14 @@ namespace llvm {
/// DIEObjectLabel - A label to an object in code or data.
//
class DIEObjectLabel : public DIEValue {
- const std::string Label;
+ const MCSymbol *Sym;
public:
- explicit DIEObjectLabel(const std::string &L)
- : DIEValue(isAsIsLabel), Label(L) {}
+ explicit DIEObjectLabel(const MCSymbol *S)
+ : DIEValue(isAsIsLabel), Sym(S) {}
/// EmitValue - Emit label value.
///
- virtual void EmitValue(Dwarf *D, unsigned Form) const;
+ virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
/// SizeOf - Determine size of label value in bytes.
///
@@ -373,7 +374,7 @@ namespace llvm {
/// EmitValue - Emit section offset.
///
- virtual void EmitValue(Dwarf *D, unsigned Form) const;
+ virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
/// SizeOf - Determine size of section offset value in bytes.
///
@@ -402,7 +403,7 @@ namespace llvm {
/// EmitValue - Emit delta value.
///
- virtual void EmitValue(Dwarf *D, unsigned Form) const;
+ virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
/// SizeOf - Determine size of delta value in bytes.
///
@@ -431,7 +432,7 @@ namespace llvm {
/// EmitValue - Emit debug information entry offset.
///
- virtual void EmitValue(Dwarf *D, unsigned Form) const;
+ virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
/// SizeOf - Determine size of debug information entry in bytes.
///
@@ -473,7 +474,7 @@ namespace llvm {
/// EmitValue - Emit block data.
///
- virtual void EmitValue(Dwarf *D, unsigned Form) const;
+ virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
/// SizeOf - Determine size of block data in bytes.
///
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 15f37ae..513987f 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -18,6 +18,7 @@
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
@@ -25,7 +26,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Mangler.h"
+#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Timer.h"
#include "llvm/System/Path.h"
using namespace llvm;
@@ -56,12 +57,12 @@ class CompileUnit {
/// GVToDieMap - Tracks the mapping of unit level debug informaton
/// variables to debug information entries.
/// FIXME : Rename GVToDieMap -> NodeToDieMap
- ValueMap<MDNode *, DIE *> GVToDieMap;
+ DenseMap<MDNode *, DIE *> GVToDieMap;
/// GVToDIEEntryMap - Tracks the mapping of unit level debug informaton
/// descriptors to debug information entries using a DIEEntry proxy.
/// FIXME : Rename
- ValueMap<MDNode *, DIEEntry *> GVToDIEEntryMap;
+ DenseMap<MDNode *, DIEEntry *> GVToDIEEntryMap;
/// Globals - A map of globally visible named entities for this unit.
///
@@ -108,7 +109,7 @@ public:
/// getDIEEntry - Returns the debug information entry for the speciefied
/// debug variable.
DIEEntry *getDIEEntry(MDNode *N) {
- ValueMap<MDNode *, DIEEntry *>::iterator I = GVToDIEEntryMap.find(N);
+ DenseMap<MDNode *, DIEEntry *>::iterator I = GVToDIEEntryMap.find(N);
if (I == GVToDIEEntryMap.end())
return NULL;
return I->second;
@@ -165,7 +166,7 @@ public:
class DbgScope {
DbgScope *Parent; // Parent to this scope.
DIDescriptor Desc; // Debug info descriptor for scope.
- WeakVH InlinedAtLocation; // Location at which scope is inlined.
+ MDNode * InlinedAtLocation; // Location at which scope is inlined.
bool AbstractScope; // Abstract Scope
unsigned StartLabelID; // Label ID of the beginning of scope.
unsigned EndLabelID; // Label ID of the end of scope.
@@ -274,7 +275,7 @@ DbgScope::~DbgScope() {
} // end llvm namespace
DwarfDebug::DwarfDebug(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T)
- : Dwarf(OS, A, T, "dbg"), ModuleCU(0),
+ : DwarfPrinter(OS, A, T, "dbg"), ModuleCU(0),
AbbreviationsSet(InitAbbreviationsSetSize), Abbreviations(),
DIEValues(), StringPool(),
SectionSourceLines(), didInitial(false), shouldEmit(false),
@@ -343,7 +344,7 @@ void DwarfDebug::addSInt(DIE *Die, unsigned Attribute,
/// addString - Add a string attribute data and value. DIEString only
/// keeps string reference.
void DwarfDebug::addString(DIE *Die, unsigned Attribute, unsigned Form,
- const StringRef String) {
+ StringRef String) {
DIEValue *Value = new DIEString(String);
DIEValues.push_back(Value);
Die->addValue(Attribute, Form, Value);
@@ -361,8 +362,8 @@ void DwarfDebug::addLabel(DIE *Die, unsigned Attribute, unsigned Form,
/// addObjectLabel - Add an non-Dwarf label attribute data and value.
///
void DwarfDebug::addObjectLabel(DIE *Die, unsigned Attribute, unsigned Form,
- const std::string &Label) {
- DIEValue *Value = new DIEObjectLabel(Label);
+ const MCSymbol *Sym) {
+ DIEValue *Value = new DIEObjectLabel(Sym);
DIEValues.push_back(Value);
Die->addValue(Attribute, Form, Value);
}
@@ -1162,7 +1163,8 @@ DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) {
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
addUInt(Block, 0, dwarf::DW_FORM_data1, SP.getVirtualIndex());
addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
- ContainingTypeMap.insert(std::make_pair(SPDie, WeakVH(SP.getContainingType().getNode())));
+ ContainingTypeMap.insert(std::make_pair(SPDie,
+ SP.getContainingType().getNode()));
}
if (MakeDecl || !SP.isDefinition()) {
@@ -1379,7 +1381,7 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
InlinedSubprogramDIEs.insert(OriginDIE);
// Track the start label for this inlined function.
- ValueMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator
+ DenseMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator
I = InlineInfo.find(InlinedSP.getNode());
if (I == InlineInfo.end()) {
@@ -1665,14 +1667,14 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
DIEBlock *Block = new DIEBlock();
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
addObjectLabel(Block, 0, dwarf::DW_FORM_udata,
- Asm->Mang->getMangledName(DI_GV.getGlobal()));
+ Asm->GetGlobalValueSymbol(DI_GV.getGlobal()));
addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
ModuleCU->addDie(VariableSpecDIE);
} else {
DIEBlock *Block = new DIEBlock();
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
addObjectLabel(Block, 0, dwarf::DW_FORM_udata,
- Asm->Mang->getMangledName(DI_GV.getGlobal()));
+ Asm->GetGlobalValueSymbol(DI_GV.getGlobal()));
addBlock(VariableDie, dwarf::DW_AT_location, 0, Block);
}
addToContextOwner(VariableDie, GVContext);
@@ -1770,13 +1772,15 @@ void DwarfDebug::beginModule(Module *M, MachineModuleInfo *mmi) {
for (unsigned i = 1, e = getNumSourceIds()+1; i != e; ++i) {
// Remember source id starts at 1.
std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(i);
+ // FIXME: don't use sys::path for this! This should not depend on the
+ // host.
sys::Path FullPath(getSourceDirectoryName(Id.first));
bool AppendOk =
FullPath.appendComponent(getSourceFileName(Id.second));
assert(AppendOk && "Could not append filename to directory!");
AppendOk = false;
Asm->EmitFile(i, FullPath.str());
- Asm->EOL();
+ Asm->O << '\n';
}
}
@@ -1808,7 +1812,7 @@ void DwarfDebug::endModule() {
TE = TopLevelDIEsVector.end(); TI != TE; ++TI)
ModuleCU->getCUDie()->addChild(*TI);
- for (DenseMap<DIE *, WeakVH>::iterator CI = ContainingTypeMap.begin(),
+ for (DenseMap<DIE *, MDNode *>::iterator CI = ContainingTypeMap.begin(),
CE = ContainingTypeMap.end(); CI != CE; ++CI) {
DIE *SPDie = CI->first;
MDNode *N = dyn_cast_or_null<MDNode>(CI->second);
@@ -1906,8 +1910,7 @@ void DwarfDebug::collectVariableInfo() {
MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo();
for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(),
VE = VMap.end(); VI != VE; ++VI) {
- MetadataBase *MB = VI->first;
- MDNode *Var = dyn_cast_or_null<MDNode>(MB);
+ MDNode *Var = VI->first;
if (!Var) continue;
DIVariable DV (Var);
std::pair< unsigned, MDNode *> VP = VI->second;
@@ -2000,13 +2003,14 @@ bool DwarfDebug::extractScopeInformation(MachineFunction *MF) {
MIIndexMap[MInsn] = MIIndex++;
DebugLoc DL = MInsn->getDebugLoc();
if (DL.isUnknown()) continue;
- DebugLocTuple DLT = MF->getDebugLocTuple(DL);
- if (!DLT.Scope) continue;
+ DILocation DLT = MF->getDILocation(DL);
+ DIScope DLTScope = DLT.getScope();
+ if (DLTScope.isNull()) continue;
// There is no need to create another DIE for compile unit. For all
// other scopes, create one DbgScope now. This will be translated
// into a scope DIE at the end.
- if (DIDescriptor(DLT.Scope).isCompileUnit()) continue;
- createDbgScope(DLT.Scope, DLT.InlinedAtLoc);
+ if (DLTScope.isCompileUnit()) continue;
+ createDbgScope(DLTScope.getNode(), DLT.getOrigLocation().getNode());
}
}
@@ -2019,13 +2023,15 @@ bool DwarfDebug::extractScopeInformation(MachineFunction *MF) {
const MachineInstr *MInsn = II;
DebugLoc DL = MInsn->getDebugLoc();
if (DL.isUnknown()) continue;
- DebugLocTuple DLT = MF->getDebugLocTuple(DL);
- if (!DLT.Scope) continue;
+ DILocation DLT = MF->getDILocation(DL);
+ DIScope DLTScope = DLT.getScope();
+ if (DLTScope.isNull()) continue;
// There is no need to create another DIE for compile unit. For all
// other scopes, create one DbgScope now. This will be translated
// into a scope DIE at the end.
- if (DIDescriptor(DLT.Scope).isCompileUnit()) continue;
- DbgScope *Scope = getUpdatedDbgScope(DLT.Scope, MInsn, DLT.InlinedAtLoc);
+ if (DLTScope.isCompileUnit()) continue;
+ DbgScope *Scope = getUpdatedDbgScope(DLTScope.getNode(), MInsn,
+ DLT.getOrigLocation().getNode());
Scope->setLastInsn(MInsn);
}
}
@@ -2038,10 +2044,18 @@ bool DwarfDebug::extractScopeInformation(MachineFunction *MF) {
// Each scope has first instruction and last instruction to mark beginning
// and end of a scope respectively. Create an inverse map that list scopes
// starts (and ends) with an instruction. One instruction may start (or end)
- // multiple scopes.
- for (ValueMap<MDNode *, DbgScope *>::iterator DI = DbgScopeMap.begin(),
- DE = DbgScopeMap.end(); DI != DE; ++DI) {
- DbgScope *S = DI->second;
+ // multiple scopes. Ignore scopes that are not reachable.
+ SmallVector<DbgScope *, 4> WorkList;
+ WorkList.push_back(CurrentFnDbgScope);
+ while (!WorkList.empty()) {
+ DbgScope *S = WorkList.back(); WorkList.pop_back();
+
+ SmallVector<DbgScope *, 4> &Children = S->getScopes();
+ if (!Children.empty())
+ for (SmallVector<DbgScope *, 4>::iterator SI = Children.begin(),
+ SE = Children.end(); SI != SE; ++SI)
+ WorkList.push_back(*SI);
+
if (S->isAbstractScope())
continue;
const MachineInstr *MI = S->getFirstInsn();
@@ -2090,13 +2104,16 @@ void DwarfDebug::beginFunction(MachineFunction *MF) {
// function.
DebugLoc FDL = MF->getDefaultDebugLoc();
if (!FDL.isUnknown()) {
- DebugLocTuple DLT = MF->getDebugLocTuple(FDL);
+ DILocation DLT = MF->getDILocation(FDL);
unsigned LabelID = 0;
- DISubprogram SP = getDISubprogram(DLT.Scope);
+ DISubprogram SP = getDISubprogram(DLT.getScope().getNode());
if (!SP.isNull())
- LabelID = recordSourceLine(SP.getLineNumber(), 0, DLT.Scope);
+ LabelID = recordSourceLine(SP.getLineNumber(), 0,
+ DLT.getScope().getNode());
else
- LabelID = recordSourceLine(DLT.Line, DLT.Col, DLT.Scope);
+ LabelID = recordSourceLine(DLT.getLineNumber(),
+ DLT.getColumnNumber(),
+ DLT.getScope().getNode());
Asm->printLabel(LabelID);
O << '\n';
}
@@ -2142,14 +2159,12 @@ void DwarfDebug::endFunction(MachineFunction *MF) {
}
// Clear debug info
- if (CurrentFnDbgScope) {
- CurrentFnDbgScope = NULL;
- DbgScopeMap.clear();
- DbgScopeBeginMap.clear();
- DbgScopeEndMap.clear();
- ConcreteScopes.clear();
- AbstractScopesList.clear();
- }
+ CurrentFnDbgScope = NULL;
+ DbgScopeMap.clear();
+ DbgScopeBeginMap.clear();
+ DbgScopeEndMap.clear();
+ ConcreteScopes.clear();
+ AbstractScopesList.clear();
Lines.clear();
if (TimePassesIsEnabled)
@@ -2332,19 +2347,15 @@ void DwarfDebug::emitDIE(DIE *Die) {
unsigned AbbrevNumber = Die->getAbbrevNumber();
const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1];
- Asm->EOL();
+ Asm->O << '\n';
// Emit the code (index) for the abbreviation.
- Asm->EmitULEB128Bytes(AbbrevNumber);
-
- if (Asm->isVerbose())
- Asm->EOL(std::string("Abbrev [" +
- utostr(AbbrevNumber) +
- "] 0x" + utohexstr(Die->getOffset()) +
- ":0x" + utohexstr(Die->getSize()) + " " +
- dwarf::TagString(Abbrev->getTag())));
- else
- Asm->EOL();
+ if (Asm->VerboseAsm)
+ Asm->OutStreamer.AddComment("Abbrev [" + Twine(AbbrevNumber) + "] 0x" +
+ Twine::utohexstr(Die->getOffset()) + ":0x" +
+ Twine::utohexstr(Die->getSize()) + " " +
+ dwarf::TagString(Abbrev->getTag()));
+ EmitULEB128(AbbrevNumber);
SmallVector<DIEValue*, 32> &Values = Die->getValues();
const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData();
@@ -2372,7 +2383,7 @@ void DwarfDebug::emitDIE(DIE *Die) {
break;
}
- Asm->EOL(dwarf::AttributeString(Attr));
+ EOL(dwarf::AttributeString(Attr));
}
// Emit the DIE children if any.
@@ -2382,7 +2393,7 @@ void DwarfDebug::emitDIE(DIE *Die) {
for (unsigned j = 0, M = Children.size(); j < M; ++j)
emitDIE(Children[j]);
- Asm->EmitInt8(0); Asm->EOL("End Of Children Mark");
+ Asm->EmitInt8(0); EOL("End Of Children Mark");
}
}
@@ -2404,21 +2415,20 @@ void DwarfDebug::emitDebugInfo() {
sizeof(int8_t) + // Pointer Size (in bytes)
sizeof(int32_t); // FIXME - extra pad for gdb bug.
- Asm->EmitInt32(ContentSize); Asm->EOL("Length of Compilation Unit Info");
- Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF version number");
+ Asm->EmitInt32(ContentSize); EOL("Length of Compilation Unit Info");
+ Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("DWARF version number");
EmitSectionOffset("abbrev_begin", "section_abbrev", 0, 0, true, false);
- Asm->EOL("Offset Into Abbrev. Section");
- Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)");
+ EOL("Offset Into Abbrev. Section");
+ Asm->EmitInt8(TD->getPointerSize()); EOL("Address Size (in bytes)");
emitDIE(Die);
// FIXME - extra padding for gdb bug.
- Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB");
- Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB");
- Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB");
- Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB");
+ Asm->EmitInt8(0); EOL("Extra Pad For GDB");
+ Asm->EmitInt8(0); EOL("Extra Pad For GDB");
+ Asm->EmitInt8(0); EOL("Extra Pad For GDB");
+ Asm->EmitInt8(0); EOL("Extra Pad For GDB");
EmitLabel("info_end", ModuleCU->getID());
-
- Asm->EOL();
+ Asm->O << '\n';
}
/// emitAbbreviations - Emit the abbreviation section.
@@ -2438,20 +2448,18 @@ void DwarfDebug::emitAbbreviations() const {
const DIEAbbrev *Abbrev = Abbreviations[i];
// Emit the abbrevations code (base 1 index.)
- Asm->EmitULEB128Bytes(Abbrev->getNumber());
- Asm->EOL("Abbreviation Code");
+ EmitULEB128(Abbrev->getNumber(), "Abbreviation Code");
// Emit the abbreviations data.
- Abbrev->Emit(Asm);
-
- Asm->EOL();
+ Abbrev->Emit(this);
+ Asm->O << '\n';
}
// Mark end of abbreviations.
- Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(3)");
+ EmitULEB128(0, "EOM(3)");
EmitLabel("abbrev_end", 0);
- Asm->EOL();
+ Asm->O << '\n';
}
}
@@ -2460,15 +2468,15 @@ void DwarfDebug::emitAbbreviations() const {
///
void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) {
// Define last address of section.
- Asm->EmitInt8(0); Asm->EOL("Extended Op");
- Asm->EmitInt8(TD->getPointerSize() + 1); Asm->EOL("Op size");
- Asm->EmitInt8(dwarf::DW_LNE_set_address); Asm->EOL("DW_LNE_set_address");
- EmitReference("section_end", SectionEnd); Asm->EOL("Section end label");
+ Asm->EmitInt8(0); EOL("Extended Op");
+ Asm->EmitInt8(TD->getPointerSize() + 1); EOL("Op size");
+ Asm->EmitInt8(dwarf::DW_LNE_set_address); EOL("DW_LNE_set_address");
+ EmitReference("section_end", SectionEnd); EOL("Section end label");
// Mark end of matrix.
- Asm->EmitInt8(0); Asm->EOL("DW_LNE_end_sequence");
- Asm->EmitULEB128Bytes(1); Asm->EOL();
- Asm->EmitInt8(1); Asm->EOL();
+ Asm->EmitInt8(0); EOL("DW_LNE_end_sequence");
+ Asm->EmitInt8(1);
+ Asm->EmitInt8(1);
}
/// emitDebugLines - Emit source line information.
@@ -2490,59 +2498,55 @@ void DwarfDebug::emitDebugLines() {
// Construct the section header.
EmitDifference("line_end", 0, "line_begin", 0, true);
- Asm->EOL("Length of Source Line Info");
+ EOL("Length of Source Line Info");
EmitLabel("line_begin", 0);
- Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF version number");
+ Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("DWARF version number");
EmitDifference("line_prolog_end", 0, "line_prolog_begin", 0, true);
- Asm->EOL("Prolog Length");
+ EOL("Prolog Length");
EmitLabel("line_prolog_begin", 0);
- Asm->EmitInt8(1); Asm->EOL("Minimum Instruction Length");
-
- Asm->EmitInt8(1); Asm->EOL("Default is_stmt_start flag");
-
- Asm->EmitInt8(MinLineDelta); Asm->EOL("Line Base Value (Special Opcodes)");
-
- Asm->EmitInt8(MaxLineDelta); Asm->EOL("Line Range Value (Special Opcodes)");
-
- Asm->EmitInt8(-MinLineDelta); Asm->EOL("Special Opcode Base");
+ Asm->EmitInt8(1); EOL("Minimum Instruction Length");
+ Asm->EmitInt8(1); EOL("Default is_stmt_start flag");
+ Asm->EmitInt8(MinLineDelta); EOL("Line Base Value (Special Opcodes)");
+ Asm->EmitInt8(MaxLineDelta); EOL("Line Range Value (Special Opcodes)");
+ Asm->EmitInt8(-MinLineDelta); EOL("Special Opcode Base");
// Line number standard opcode encodings argument count
- Asm->EmitInt8(0); Asm->EOL("DW_LNS_copy arg count");
- Asm->EmitInt8(1); Asm->EOL("DW_LNS_advance_pc arg count");
- Asm->EmitInt8(1); Asm->EOL("DW_LNS_advance_line arg count");
- Asm->EmitInt8(1); Asm->EOL("DW_LNS_set_file arg count");
- Asm->EmitInt8(1); Asm->EOL("DW_LNS_set_column arg count");
- Asm->EmitInt8(0); Asm->EOL("DW_LNS_negate_stmt arg count");
- Asm->EmitInt8(0); Asm->EOL("DW_LNS_set_basic_block arg count");
- Asm->EmitInt8(0); Asm->EOL("DW_LNS_const_add_pc arg count");
- Asm->EmitInt8(1); Asm->EOL("DW_LNS_fixed_advance_pc arg count");
+ Asm->EmitInt8(0); EOL("DW_LNS_copy arg count");
+ Asm->EmitInt8(1); EOL("DW_LNS_advance_pc arg count");
+ Asm->EmitInt8(1); EOL("DW_LNS_advance_line arg count");
+ Asm->EmitInt8(1); EOL("DW_LNS_set_file arg count");
+ Asm->EmitInt8(1); EOL("DW_LNS_set_column arg count");
+ Asm->EmitInt8(0); EOL("DW_LNS_negate_stmt arg count");
+ Asm->EmitInt8(0); EOL("DW_LNS_set_basic_block arg count");
+ Asm->EmitInt8(0); EOL("DW_LNS_const_add_pc arg count");
+ Asm->EmitInt8(1); EOL("DW_LNS_fixed_advance_pc arg count");
// Emit directories.
for (unsigned DI = 1, DE = getNumSourceDirectories()+1; DI != DE; ++DI) {
- Asm->EmitString(getSourceDirectoryName(DI));
- Asm->EOL("Directory");
+ const std::string &Dir = getSourceDirectoryName(DI);
+ if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("Directory");
+ Asm->OutStreamer.EmitBytes(StringRef(Dir.c_str(), Dir.size()+1), 0);
}
- Asm->EmitInt8(0); Asm->EOL("End of directories");
+ Asm->EmitInt8(0); EOL("End of directories");
// Emit files.
for (unsigned SI = 1, SE = getNumSourceIds()+1; SI != SE; ++SI) {
// Remember source id starts at 1.
std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(SI);
- Asm->EmitString(getSourceFileName(Id.second));
- Asm->EOL("Source");
- Asm->EmitULEB128Bytes(Id.first);
- Asm->EOL("Directory #");
- Asm->EmitULEB128Bytes(0);
- Asm->EOL("Mod date");
- Asm->EmitULEB128Bytes(0);
- Asm->EOL("File size");
+ const std::string &FN = getSourceFileName(Id.second);
+ if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("Source");
+ Asm->OutStreamer.EmitBytes(StringRef(FN.c_str(), FN.size()+1), 0);
+
+ EmitULEB128(Id.first, "Directory #");
+ EmitULEB128(0, "Mod date");
+ EmitULEB128(0, "File size");
}
- Asm->EmitInt8(0); Asm->EOL("End of files");
+ Asm->EmitInt8(0); EOL("End of files");
EmitLabel("line_prolog_end", 0);
@@ -2558,7 +2562,7 @@ void DwarfDebug::emitDebugLines() {
O << '\t' << MAI->getCommentString() << " Section"
<< S->getName() << '\n';
}*/
- Asm->EOL();
+ Asm->O << '\n';
// Dwarf assumes we start with first line of first source file.
unsigned Source = 1;
@@ -2573,7 +2577,7 @@ void DwarfDebug::emitDebugLines() {
if (LineInfo.getLine() == 0) continue;
if (!Asm->isVerbose())
- Asm->EOL();
+ Asm->O << '\n';
else {
std::pair<unsigned, unsigned> SourceID =
getSourceDirectoryAndFileIds(LineInfo.getSourceID());
@@ -2584,16 +2588,16 @@ void DwarfDebug::emitDebugLines() {
}
// Define the line address.
- Asm->EmitInt8(0); Asm->EOL("Extended Op");
- Asm->EmitInt8(TD->getPointerSize() + 1); Asm->EOL("Op size");
- Asm->EmitInt8(dwarf::DW_LNE_set_address); Asm->EOL("DW_LNE_set_address");
- EmitReference("label", LabelID); Asm->EOL("Location label");
+ Asm->EmitInt8(0); EOL("Extended Op");
+ Asm->EmitInt8(TD->getPointerSize() + 1); EOL("Op size");
+ Asm->EmitInt8(dwarf::DW_LNE_set_address); EOL("DW_LNE_set_address");
+ EmitReference("label", LabelID); EOL("Location label");
// If change of source, then switch to the new source.
if (Source != LineInfo.getSourceID()) {
Source = LineInfo.getSourceID();
- Asm->EmitInt8(dwarf::DW_LNS_set_file); Asm->EOL("DW_LNS_set_file");
- Asm->EmitULEB128Bytes(Source); Asm->EOL("New Source");
+ Asm->EmitInt8(dwarf::DW_LNS_set_file); EOL("DW_LNS_set_file");
+ EmitULEB128(Source, "New Source");
}
// If change of line.
@@ -2608,17 +2612,17 @@ void DwarfDebug::emitDebugLines() {
// If delta is small enough and in range...
if (Delta >= 0 && Delta < (MaxLineDelta - 1)) {
// ... then use fast opcode.
- Asm->EmitInt8(Delta - MinLineDelta); Asm->EOL("Line Delta");
+ Asm->EmitInt8(Delta - MinLineDelta); EOL("Line Delta");
} else {
// ... otherwise use long hand.
Asm->EmitInt8(dwarf::DW_LNS_advance_line);
- Asm->EOL("DW_LNS_advance_line");
- Asm->EmitSLEB128Bytes(Offset); Asm->EOL("Line Offset");
- Asm->EmitInt8(dwarf::DW_LNS_copy); Asm->EOL("DW_LNS_copy");
+ EOL("DW_LNS_advance_line");
+ EmitSLEB128(Offset, "Line Offset");
+ Asm->EmitInt8(dwarf::DW_LNS_copy); EOL("DW_LNS_copy");
}
} else {
// Copy the previous row (different address or source)
- Asm->EmitInt8(dwarf::DW_LNS_copy); Asm->EOL("DW_LNS_copy");
+ Asm->EmitInt8(dwarf::DW_LNS_copy); EOL("DW_LNS_copy");
}
}
@@ -2632,7 +2636,7 @@ void DwarfDebug::emitDebugLines() {
emitEndOfLineMatrix(1);
EmitLabel("line_end", 0);
- Asm->EOL();
+ Asm->O << '\n';
}
/// emitCommonDebugFrame - Emit common frame info into a debug frame section.
@@ -2653,21 +2657,19 @@ void DwarfDebug::emitCommonDebugFrame() {
EmitLabel("debug_frame_common", 0);
EmitDifference("debug_frame_common_end", 0,
"debug_frame_common_begin", 0, true);
- Asm->EOL("Length of Common Information Entry");
+ EOL("Length of Common Information Entry");
EmitLabel("debug_frame_common_begin", 0);
Asm->EmitInt32((int)dwarf::DW_CIE_ID);
- Asm->EOL("CIE Identifier Tag");
+ EOL("CIE Identifier Tag");
Asm->EmitInt8(dwarf::DW_CIE_VERSION);
- Asm->EOL("CIE Version");
- Asm->EmitString("");
- Asm->EOL("CIE Augmentation");
- Asm->EmitULEB128Bytes(1);
- Asm->EOL("CIE Code Alignment Factor");
- Asm->EmitSLEB128Bytes(stackGrowth);
- Asm->EOL("CIE Data Alignment Factor");
+ EOL("CIE Version");
+ Asm->OutStreamer.EmitIntValue(0, 1, /*addrspace*/0); // nul terminator.
+ EOL("CIE Augmentation");
+ EmitULEB128(1, "CIE Code Alignment Factor");
+ EmitSLEB128(stackGrowth, "CIE Data Alignment Factor");
Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), false));
- Asm->EOL("CIE RA Column");
+ EOL("CIE RA Column");
std::vector<MachineMove> Moves;
RI->getInitialFrameState(Moves);
@@ -2676,8 +2678,7 @@ void DwarfDebug::emitCommonDebugFrame() {
Asm->EmitAlignment(2, 0, 0, false);
EmitLabel("debug_frame_common_end", 0);
-
- Asm->EOL();
+ Asm->O << '\n';
}
/// emitFunctionDebugFrame - Emit per function frame info into a debug frame
@@ -2693,27 +2694,26 @@ DwarfDebug::emitFunctionDebugFrame(const FunctionDebugFrameInfo&DebugFrameInfo){
EmitDifference("debug_frame_end", DebugFrameInfo.Number,
"debug_frame_begin", DebugFrameInfo.Number, true);
- Asm->EOL("Length of Frame Information Entry");
+ EOL("Length of Frame Information Entry");
EmitLabel("debug_frame_begin", DebugFrameInfo.Number);
EmitSectionOffset("debug_frame_common", "section_debug_frame",
0, 0, true, false);
- Asm->EOL("FDE CIE offset");
+ EOL("FDE CIE offset");
EmitReference("func_begin", DebugFrameInfo.Number);
- Asm->EOL("FDE initial location");
+ EOL("FDE initial location");
EmitDifference("func_end", DebugFrameInfo.Number,
"func_begin", DebugFrameInfo.Number);
- Asm->EOL("FDE address range");
+ EOL("FDE address range");
EmitFrameMoves("func_begin", DebugFrameInfo.Number, DebugFrameInfo.Moves,
false);
Asm->EmitAlignment(2, 0, 0, false);
EmitLabel("debug_frame_end", DebugFrameInfo.Number);
-
- Asm->EOL();
+ Asm->O << '\n';
}
/// emitDebugPubNames - Emit visible names into a debug pubnames section.
@@ -2725,19 +2725,19 @@ void DwarfDebug::emitDebugPubNames() {
EmitDifference("pubnames_end", ModuleCU->getID(),
"pubnames_begin", ModuleCU->getID(), true);
- Asm->EOL("Length of Public Names Info");
+ EOL("Length of Public Names Info");
EmitLabel("pubnames_begin", ModuleCU->getID());
- Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF Version");
+ Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("DWARF Version");
EmitSectionOffset("info_begin", "section_info",
ModuleCU->getID(), 0, true, false);
- Asm->EOL("Offset of Compilation Unit Info");
+ EOL("Offset of Compilation Unit Info");
EmitDifference("info_end", ModuleCU->getID(), "info_begin", ModuleCU->getID(),
true);
- Asm->EOL("Compilation Unit Length");
+ EOL("Compilation Unit Length");
const StringMap<DIE*> &Globals = ModuleCU->getGlobals();
for (StringMap<DIE*>::const_iterator
@@ -2745,14 +2745,16 @@ void DwarfDebug::emitDebugPubNames() {
const char *Name = GI->getKeyData();
DIE * Entity = GI->second;
- Asm->EmitInt32(Entity->getOffset()); Asm->EOL("DIE offset");
- Asm->EmitString(Name, strlen(Name)); Asm->EOL("External Name");
+ Asm->EmitInt32(Entity->getOffset()); EOL("DIE offset");
+
+ if (Asm->VerboseAsm)
+ Asm->OutStreamer.AddComment("External Name");
+ Asm->OutStreamer.EmitBytes(StringRef(Name, strlen(Name)+1), 0);
}
- Asm->EmitInt32(0); Asm->EOL("End Mark");
+ Asm->EmitInt32(0); EOL("End Mark");
EmitLabel("pubnames_end", ModuleCU->getID());
-
- Asm->EOL();
+ Asm->O << '\n';
}
void DwarfDebug::emitDebugPubTypes() {
@@ -2761,19 +2763,19 @@ void DwarfDebug::emitDebugPubTypes() {
Asm->getObjFileLowering().getDwarfPubTypesSection());
EmitDifference("pubtypes_end", ModuleCU->getID(),
"pubtypes_begin", ModuleCU->getID(), true);
- Asm->EOL("Length of Public Types Info");
+ EOL("Length of Public Types Info");
EmitLabel("pubtypes_begin", ModuleCU->getID());
- Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF Version");
+ Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("DWARF Version");
EmitSectionOffset("info_begin", "section_info",
ModuleCU->getID(), 0, true, false);
- Asm->EOL("Offset of Compilation ModuleCU Info");
+ EOL("Offset of Compilation ModuleCU Info");
EmitDifference("info_end", ModuleCU->getID(), "info_begin", ModuleCU->getID(),
true);
- Asm->EOL("Compilation ModuleCU Length");
+ EOL("Compilation ModuleCU Length");
const StringMap<DIE*> &Globals = ModuleCU->getGlobalTypes();
for (StringMap<DIE*>::const_iterator
@@ -2781,14 +2783,15 @@ void DwarfDebug::emitDebugPubTypes() {
const char *Name = GI->getKeyData();
DIE * Entity = GI->second;
- Asm->EmitInt32(Entity->getOffset()); Asm->EOL("DIE offset");
- Asm->EmitString(Name, strlen(Name)); Asm->EOL("External Name");
+ Asm->EmitInt32(Entity->getOffset()); EOL("DIE offset");
+
+ if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("External Name");
+ Asm->OutStreamer.EmitBytes(StringRef(Name, strlen(Name)), 0);
}
- Asm->EmitInt32(0); Asm->EOL("End Mark");
+ Asm->EmitInt32(0); EOL("End Mark");
EmitLabel("pubtypes_end", ModuleCU->getID());
-
- Asm->EOL();
+ Asm->O << '\n';
}
/// emitDebugStr - Emit visible names into a debug str section.
@@ -2808,10 +2811,10 @@ void DwarfDebug::emitDebugStr() {
// Emit the string itself.
const std::string &String = StringPool[StringID];
- Asm->EmitString(String); Asm->EOL();
+ Asm->OutStreamer.EmitBytes(StringRef(String.c_str(), String.size()+1), 0);
}
- Asm->EOL();
+ Asm->O << '\n';
}
}
@@ -2821,7 +2824,6 @@ void DwarfDebug::emitDebugLoc() {
// Start the dwarf loc section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfLocSection());
- Asm->EOL();
}
/// EmitDebugARanges - Emit visible names into a debug aranges section.
@@ -2836,29 +2838,27 @@ void DwarfDebug::EmitDebugARanges() {
CompileUnit *Unit = GetBaseCompileUnit();
// Don't include size of length
- Asm->EmitInt32(0x1c); Asm->EOL("Length of Address Ranges Info");
+ Asm->EmitInt32(0x1c); EOL("Length of Address Ranges Info");
- Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("Dwarf Version");
+ Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("Dwarf Version");
EmitReference("info_begin", Unit->getID());
- Asm->EOL("Offset of Compilation Unit Info");
+ EOL("Offset of Compilation Unit Info");
- Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Size of Address");
+ Asm->EmitInt8(TD->getPointerSize()); EOL("Size of Address");
- Asm->EmitInt8(0); Asm->EOL("Size of Segment Descriptor");
+ Asm->EmitInt8(0); EOL("Size of Segment Descriptor");
- Asm->EmitInt16(0); Asm->EOL("Pad (1)");
- Asm->EmitInt16(0); Asm->EOL("Pad (2)");
+ Asm->EmitInt16(0); EOL("Pad (1)");
+ Asm->EmitInt16(0); EOL("Pad (2)");
// Range 1
- EmitReference("text_begin", 0); Asm->EOL("Address");
- EmitDifference("text_end", 0, "text_begin", 0, true); Asm->EOL("Length");
+ EmitReference("text_begin", 0); EOL("Address");
+ EmitDifference("text_end", 0, "text_begin", 0, true); EOL("Length");
- Asm->EmitInt32(0); Asm->EOL("EOM (1)");
- Asm->EmitInt32(0); Asm->EOL("EOM (2)");
+ Asm->EmitInt32(0); EOL("EOM (1)");
+ Asm->EmitInt32(0); EOL("EOM (2)");
#endif
-
- Asm->EOL();
}
/// emitDebugRanges - Emit visible names into a debug ranges section.
@@ -2867,7 +2867,6 @@ void DwarfDebug::emitDebugRanges() {
// Start the dwarf ranges section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfRangesSection());
- Asm->EOL();
}
/// emitDebugMacInfo - Emit visible names into a debug macinfo section.
@@ -2877,7 +2876,6 @@ void DwarfDebug::emitDebugMacInfo() {
Asm->getObjFileLowering().getDwarfMacroInfoSection()) {
// Start the dwarf macinfo section.
Asm->OutStreamer.SwitchSection(LineInfo);
- Asm->EOL();
}
}
@@ -2908,53 +2906,54 @@ void DwarfDebug::emitDebugInlineInfo() {
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfDebugInlineSection());
- Asm->EOL();
+
EmitDifference("debug_inlined_end", 1,
"debug_inlined_begin", 1, true);
- Asm->EOL("Length of Debug Inlined Information Entry");
+ EOL("Length of Debug Inlined Information Entry");
EmitLabel("debug_inlined_begin", 1);
- Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("Dwarf Version");
- Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)");
+ Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("Dwarf Version");
+ Asm->EmitInt8(TD->getPointerSize()); EOL("Address Size (in bytes)");
for (SmallVector<MDNode *, 4>::iterator I = InlinedSPNodes.begin(),
E = InlinedSPNodes.end(); I != E; ++I) {
MDNode *Node = *I;
- ValueMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator II
+ DenseMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator II
= InlineInfo.find(Node);
SmallVector<InlineInfoLabels, 4> &Labels = II->second;
DISubprogram SP(Node);
StringRef LName = SP.getLinkageName();
StringRef Name = SP.getName();
- if (LName.empty())
- Asm->EmitString(Name);
- else
+ if (LName.empty()) {
+ Asm->OutStreamer.EmitBytes(Name, 0);
+ Asm->OutStreamer.EmitIntValue(0, 1, 0); // nul terminator.
+ } else
EmitSectionOffset("string", "section_str",
- StringPool.idFor(getRealLinkageName(LName)), false, true);
+ StringPool.idFor(getRealLinkageName(LName)), false, true);
- Asm->EOL("MIPS linkage name");
+ EOL("MIPS linkage name");
EmitSectionOffset("string", "section_str",
StringPool.idFor(Name), false, true);
- Asm->EOL("Function name");
- Asm->EmitULEB128Bytes(Labels.size()); Asm->EOL("Inline count");
+ EOL("Function name");
+ EmitULEB128(Labels.size(), "Inline count");
for (SmallVector<InlineInfoLabels, 4>::iterator LI = Labels.begin(),
LE = Labels.end(); LI != LE; ++LI) {
DIE *SP = LI->second;
- Asm->EmitInt32(SP->getOffset()); Asm->EOL("DIE offset");
+ Asm->EmitInt32(SP->getOffset()); EOL("DIE offset");
if (TD->getPointerSize() == sizeof(int32_t))
O << MAI->getData32bitsDirective();
else
O << MAI->getData64bitsDirective();
- PrintLabelName("label", LI->first); Asm->EOL("low_pc");
+ PrintLabelName("label", LI->first); EOL("low_pc");
}
}
EmitLabel("debug_inlined_end", 1);
- Asm->EOL();
+ Asm->O << '\n';
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 2b8164e..e723621 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -20,7 +20,7 @@
#include "llvm/CodeGen/MachineLocation.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/ADT/ValueMap.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringMap.h"
@@ -57,7 +57,7 @@ public:
unsigned getLabelID() const { return LabelID; }
};
-class DwarfDebug : public Dwarf {
+class DwarfDebug : public DwarfPrinter {
//===--------------------------------------------------------------------===//
// Attributes used to construct specific Dwarf sections.
//
@@ -136,25 +136,25 @@ class DwarfDebug : public Dwarf {
/// DbgScopeMap - Tracks the scopes in the current function.
///
- ValueMap<MDNode *, DbgScope *> DbgScopeMap;
+ DenseMap<MDNode *, DbgScope *> DbgScopeMap;
/// ConcreteScopes - Tracks the concrete scopees in the current function.
/// These scopes are also included in DbgScopeMap.
- ValueMap<MDNode *, DbgScope *> ConcreteScopes;
+ DenseMap<MDNode *, DbgScope *> ConcreteScopes;
/// AbstractScopes - Tracks the abstract scopes a module. These scopes are
/// not included DbgScopeMap.
- ValueMap<MDNode *, DbgScope *> AbstractScopes;
+ DenseMap<MDNode *, DbgScope *> AbstractScopes;
SmallVector<DbgScope *, 4>AbstractScopesList;
/// AbstractVariables - Collection on abstract variables.
- ValueMap<MDNode *, DbgVariable *> AbstractVariables;
+ DenseMap<MDNode *, DbgVariable *> AbstractVariables;
/// InliendSubprogramDIEs - Collection of subprgram DIEs that are marked
/// (at the end of the module) as DW_AT_inline.
SmallPtrSet<DIE *, 4> InlinedSubprogramDIEs;
- DenseMap<DIE *, WeakVH> ContainingTypeMap;
+ DenseMap<DIE *, MDNode *> ContainingTypeMap;
/// AbstractSubprogramDIEs - Collection of abstruct subprogram DIEs.
SmallPtrSet<DIE *, 4> AbstractSubprogramDIEs;
@@ -176,7 +176,7 @@ class DwarfDebug : public Dwarf {
/// InlineInfo - Keep track of inlined functions and their location. This
/// information is used to populate debug_inlined section.
typedef std::pair<unsigned, DIE *> InlineInfoLabels;
- ValueMap<MDNode *, SmallVector<InlineInfoLabels, 4> > InlineInfo;
+ DenseMap<MDNode *, SmallVector<InlineInfoLabels, 4> > InlineInfo;
SmallVector<MDNode *, 4> InlinedSPNodes;
/// CompileUnitOffsets - A vector of the offsets of the compile units. This is
@@ -256,7 +256,7 @@ class DwarfDebug : public Dwarf {
/// addObjectLabel - Add an non-Dwarf label attribute data and value.
///
void addObjectLabel(DIE *Die, unsigned Attribute, unsigned Form,
- const std::string &Label);
+ const MCSymbol *Sym);
/// addSectionOffset - Add a section offset label attribute data and value.
///
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp
index d01f300..2ae16c0 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp
@@ -22,22 +22,23 @@
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/Dwarf.h"
-#include "llvm/Support/Mangler.h"
+#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Timer.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
using namespace llvm;
DwarfException::DwarfException(raw_ostream &OS, AsmPrinter *A,
const MCAsmInfo *T)
- : Dwarf(OS, A, T, "eh"), shouldEmitTable(false), shouldEmitMoves(false),
+ : DwarfPrinter(OS, A, T, "eh"), shouldEmitTable(false),shouldEmitMoves(false),
shouldEmitTableModule(false), shouldEmitMovesModule(false),
ExceptionTimer(0) {
if (TimePassesIsEnabled)
@@ -114,14 +115,14 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
// Define the eh frame length.
EmitDifference("eh_frame_common_end", Index,
"eh_frame_common_begin", Index, true);
- Asm->EOL("Length of Common Information Entry");
+ EOL("Length of Common Information Entry");
// EH frame header.
EmitLabel("eh_frame_common_begin", Index);
- Asm->EmitInt32((int)0);
- Asm->EOL("CIE Identifier Tag");
- Asm->EmitInt8(dwarf::DW_CIE_VERSION);
- Asm->EOL("CIE Version");
+ if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("CIE Identifier Tag");
+ Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
+ if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("DW_CIE_VERSION");
+ Asm->OutStreamer.EmitIntValue(dwarf::DW_CIE_VERSION, 1/*size*/, 0/*addr*/);
// The personality presence indicates that language specific information will
// show up in the eh frame. Find out how we are supposed to lower the
@@ -145,7 +146,7 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
unsigned LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
unsigned FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
- char Augmentation[5] = { 0 };
+ char Augmentation[6] = { 0 };
unsigned AugmentationSize = 0;
char *APtr = Augmentation + 1;
@@ -170,22 +171,17 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
if (APtr != Augmentation + 1)
Augmentation[0] = 'z';
- Asm->EmitString(Augmentation);
- Asm->EOL("CIE Augmentation");
+ Asm->OutStreamer.EmitBytes(StringRef(Augmentation, strlen(Augmentation)+1),0);
+ EOL("CIE Augmentation");
// Round out reader.
- Asm->EmitULEB128Bytes(1);
- Asm->EOL("CIE Code Alignment Factor");
- Asm->EmitSLEB128Bytes(stackGrowth);
- Asm->EOL("CIE Data Alignment Factor");
+ EmitULEB128(1, "CIE Code Alignment Factor");
+ EmitSLEB128(stackGrowth, "CIE Data Alignment Factor");
Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true));
- Asm->EOL("CIE Return Address Column");
+ EOL("CIE Return Address Column");
- Asm->EmitULEB128Bytes(AugmentationSize);
- Asm->EOL("Augmentation Size");
-
- Asm->EmitInt8(PerEncoding);
- Asm->EOL("Personality", PerEncoding);
+ EmitULEB128(AugmentationSize, "Augmentation Size");
+ EmitEncodingByte(PerEncoding, "Personality");
// If there is a personality, we need to indicate the function's location.
if (PersonalityRef) {
@@ -193,15 +189,11 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
PersonalityRef = CreateLabelDiff(PersonalityRef, "personalityref_addr",
Index);
- O << MAI->getData32bitsDirective();
- PersonalityRef->print(O, MAI);
- Asm->EOL("Personality");
-
- Asm->EmitInt8(LSDAEncoding);
- Asm->EOL("LSDA Encoding", LSDAEncoding);
+ O << MAI->getData32bitsDirective() << *PersonalityRef;
+ EOL("Personality");
- Asm->EmitInt8(FDEEncoding);
- Asm->EOL("FDE Encoding", FDEEncoding);
+ EmitEncodingByte(LSDAEncoding, "LSDA");
+ EmitEncodingByte(FDEEncoding, "FDE");
}
// Indicate locations of general callee saved registers in frame.
@@ -214,8 +206,7 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
// holes which confuse readers of eh_frame.
Asm->EmitAlignment(TD->getPointerSize() == 4 ? 2 : 3, 0, 0, false);
EmitLabel("eh_frame_common_end", Index);
-
- Asm->EOL();
+ Asm->O << '\n';
}
/// EmitFDE - Emit the Frame Description Entry (FDE) for the function.
@@ -231,16 +222,17 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
// corresponding function is static, this should not be externally visible.
if (!TheFunc->hasLocalLinkage())
if (const char *GlobalEHDirective = MAI->getGlobalEHDirective())
- O << GlobalEHDirective << EHFrameInfo.FnName << '\n';
+ O << GlobalEHDirective << *EHFrameInfo.FunctionEHSym << '\n';
// If corresponding function is weak definition, this should be too.
if (TheFunc->isWeakForLinker() && MAI->getWeakDefDirective())
- O << MAI->getWeakDefDirective() << EHFrameInfo.FnName << '\n';
+ O << MAI->getWeakDefDirective() << *EHFrameInfo.FunctionEHSym << '\n';
// If corresponding function is hidden, this should be too.
if (TheFunc->hasHiddenVisibility())
- if (const char *HiddenDirective = MAI->getHiddenDirective())
- O << HiddenDirective << EHFrameInfo.FnName << '\n' ;
+ if (MCSymbolAttr HiddenAttr = MAI->getHiddenVisibilityAttr())
+ Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,
+ HiddenAttr);
// If there are no calls then you can't unwind. This may mean we can omit the
// EH Frame, but some environments do not handle weak absolute symbols. If
@@ -250,19 +242,20 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
(!TheFunc->isWeakForLinker() ||
!MAI->getWeakDefDirective() ||
MAI->getSupportsWeakOmittedEHFrame())) {
- O << EHFrameInfo.FnName << " = 0\n";
+ O << *EHFrameInfo.FunctionEHSym << " = 0\n";
// This name has no connection to the function, so it might get
// dead-stripped when the function is not, erroneously. Prohibit
// dead-stripping unconditionally.
- if (const char *UsedDirective = MAI->getUsedDirective())
- O << UsedDirective << EHFrameInfo.FnName << "\n\n";
+ if (MAI->hasNoDeadStrip())
+ Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,
+ MCSA_NoDeadStrip);
} else {
- O << EHFrameInfo.FnName << ":\n";
+ O << *EHFrameInfo.FunctionEHSym << ":\n";
// EH frame header.
EmitDifference("eh_frame_end", EHFrameInfo.Number,
"eh_frame_begin", EHFrameInfo.Number, true);
- Asm->EOL("Length of Frame Information Entry");
+ EOL("Length of Frame Information Entry");
EmitLabel("eh_frame_begin", EHFrameInfo.Number);
@@ -270,34 +263,39 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
EHFrameInfo.Number, EHFrameInfo.PersonalityIndex,
true, true, false);
- Asm->EOL("FDE CIE offset");
+ EOL("FDE CIE offset");
EmitReference("eh_func_begin", EHFrameInfo.Number, true, true);
- Asm->EOL("FDE initial location");
+ EOL("FDE initial location");
EmitDifference("eh_func_end", EHFrameInfo.Number,
"eh_func_begin", EHFrameInfo.Number, true);
- Asm->EOL("FDE address range");
+ EOL("FDE address range");
// If there is a personality and landing pads then point to the language
// specific data area in the exception table.
if (MMI->getPersonalities()[0] != NULL) {
- bool is4Byte = TD->getPointerSize() == sizeof(int32_t);
- Asm->EmitULEB128Bytes(is4Byte ? 4 : 8);
- Asm->EOL("Augmentation size");
+ if (Asm->TM.getLSDAEncoding() != DwarfLSDAEncoding::EightByte) {
+ EmitULEB128(4, "Augmentation size");
- if (EHFrameInfo.hasLandingPads)
- EmitReference("exception", EHFrameInfo.Number, true, false);
- else {
- if (is4Byte)
- Asm->EmitInt32((int)0);
+ if (EHFrameInfo.hasLandingPads)
+ EmitReference("exception", EHFrameInfo.Number, true, true);
else
- Asm->EmitInt64((int)0);
+ Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
+ } else {
+ EmitULEB128(TD->getPointerSize(), "Augmentation size");
+
+ if (EHFrameInfo.hasLandingPads) {
+ EmitReference("exception", EHFrameInfo.Number, true, false);
+ } else {
+ Asm->OutStreamer.EmitIntValue(0, TD->getPointerSize(),
+ 0/*addrspace*/);
+ }
}
- Asm->EOL("Language Specific Data Area");
+
+ EOL("Language Specific Data Area");
} else {
- Asm->EmitULEB128Bytes(0);
- Asm->EOL("Augmentation size");
+ EmitULEB128(0, "Augmentation size");
}
// Indicate locations of function specific callee saved registers in frame.
@@ -317,11 +315,11 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
// on unused functions (calling undefined externals) being dead-stripped to
// link correctly. Yes, there really is.
if (MMI->isUsedFunction(EHFrameInfo.function))
- if (const char *UsedDirective = MAI->getUsedDirective())
- O << UsedDirective << EHFrameInfo.FnName << "\n\n";
+ if (MAI->hasNoDeadStrip())
+ Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,
+ MCSA_NoDeadStrip);
}
-
- Asm->EOL();
+ Asm->O << '\n';
}
/// SharedTypeIds - How many leading type ids two landing pads have in common.
@@ -765,7 +763,7 @@ void DwarfException::EmitExceptionTable() {
for (unsigned i = 0; i != SizeAlign; ++i) {
Asm->EmitInt8(0);
- Asm->EOL("Padding");
+ EOL("Padding");
}
EmitLabel("exception", SubprogramCount);
@@ -778,23 +776,16 @@ void DwarfException::EmitExceptionTable() {
}
// Emit the header.
- Asm->EmitInt8(dwarf::DW_EH_PE_omit);
- Asm->EOL("@LPStart format", dwarf::DW_EH_PE_omit);
+ EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
+ EmitEncodingByte(TTypeFormat, "@TType");
- Asm->EmitInt8(TTypeFormat);
- Asm->EOL("@TType format", TTypeFormat);
-
- if (HaveTTData) {
- Asm->EmitULEB128Bytes(TyOffset);
- Asm->EOL("@TType base offset");
- }
+ if (HaveTTData)
+ EmitULEB128(TyOffset, "@TType base offset");
// SjLj Exception handling
if (IsSJLJ) {
- Asm->EmitInt8(dwarf::DW_EH_PE_udata4);
- Asm->EOL("Call site format", dwarf::DW_EH_PE_udata4);
- Asm->EmitULEB128Bytes(SizeSites);
- Asm->EOL("Call site table length");
+ EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
+ EmitULEB128(SizeSites, "Call site table length");
// Emit the landing pad site information.
unsigned idx = 0;
@@ -804,14 +795,12 @@ void DwarfException::EmitExceptionTable() {
// Offset of the landing pad, counted in 16-byte bundles relative to the
// @LPStart address.
- Asm->EmitULEB128Bytes(idx);
- Asm->EOL("Landing pad");
+ EmitULEB128(idx, "Landing pad");
// Offset of the first associated action record, relative to the start of
// the action table. This value is biased by 1 (1 indicates the start of
// the action table), and 0 indicates that there are no actions.
- Asm->EmitULEB128Bytes(S.Action);
- Asm->EOL("Action");
+ EmitULEB128(S.Action, "Action");
}
} else {
// DWARF Exception handling
@@ -836,10 +825,8 @@ void DwarfException::EmitExceptionTable() {
// supposed to throw.
// Emit the landing pad call site table.
- Asm->EmitInt8(dwarf::DW_EH_PE_udata4);
- Asm->EOL("Call site format", dwarf::DW_EH_PE_udata4);
- Asm->EmitULEB128Bytes(SizeSites);
- Asm->EOL("Call site table size");
+ EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
+ EmitULEB128(SizeSites, "Call site table size");
for (SmallVectorImpl<CallSiteEntry>::const_iterator
I = CallSites.begin(), E = CallSites.end(); I != E; ++I) {
@@ -860,7 +847,7 @@ void DwarfException::EmitExceptionTable() {
// the start of the procedure fragment.
EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount,
true, true);
- Asm->EOL("Region start");
+ EOL("Region start");
if (!S.EndLabel)
EmitDifference("eh_func_end", SubprogramCount, BeginTag, BeginNumber,
@@ -868,23 +855,22 @@ void DwarfException::EmitExceptionTable() {
else
EmitDifference("label", S.EndLabel, BeginTag, BeginNumber, true);
- Asm->EOL("Region length");
+ EOL("Region length");
// Offset of the landing pad, counted in 16-byte bundles relative to the
// @LPStart address.
if (!S.PadLabel)
- Asm->EmitInt32(0);
+ Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
else
EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount,
true, true);
- Asm->EOL("Landing pad");
+ EOL("Landing pad");
// Offset of the first associated action record, relative to the start of
// the action table. This value is biased by 1 (1 indicates the start of
// the action table), and 0 indicates that there are no actions.
- Asm->EmitULEB128Bytes(S.Action);
- Asm->EOL("Action");
+ EmitULEB128(S.Action, "Action");
}
}
@@ -897,17 +883,13 @@ void DwarfException::EmitExceptionTable() {
//
// Used by the runtime to match the type of the thrown exception to the
// type of the catch clauses or the types in the exception specification.
-
- Asm->EmitSLEB128Bytes(Action.ValueForTypeID);
- Asm->EOL("TypeInfo index");
+ EmitSLEB128(Action.ValueForTypeID, "TypeInfo index");
// Action Record
//
// Self-relative signed displacement in bytes of the next action record,
// or 0 if there is no next action record.
-
- Asm->EmitSLEB128Bytes(Action.NextAction);
- Asm->EOL("Next action");
+ EmitSLEB128(Action.NextAction, "Next action");
}
// Emit the Catch TypeInfos.
@@ -916,24 +898,19 @@ void DwarfException::EmitExceptionTable() {
const GlobalVariable *GV = *I;
PrintRelDirective();
- if (GV) {
- O << Asm->Mang->getMangledName(GV);
- } else {
+ if (GV)
+ O << *Asm->GetGlobalValueSymbol(GV);
+ else
O << "0x0";
- }
- Asm->EOL("TypeInfo");
+ EOL("TypeInfo");
}
// Emit the Exception Specifications.
for (std::vector<unsigned>::const_iterator
I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
unsigned TypeID = *I;
- Asm->EmitULEB128Bytes(TypeID);
- if (TypeID != 0)
- Asm->EOL("Exception specification");
- else
- Asm->EOL();
+ EmitULEB128(TypeID, TypeID != 0 ? "Exception specification" : 0);
}
Asm->EmitAlignment(2, 0, 0, false);
@@ -1008,12 +985,12 @@ void DwarfException::EndFunction() {
EmitLabel("eh_func_end", SubprogramCount);
EmitExceptionTable();
- std::string FunctionEHName =
- Asm->Mang->getMangledName(MF->getFunction(), ".eh",
- Asm->MAI->is_EHSymbolPrivate());
+ MCSymbol *FunctionEHSym =
+ Asm->GetSymbolWithGlobalValueBase(MF->getFunction(), ".eh",
+ Asm->MAI->is_EHSymbolPrivate());
// Save EH frame information
- EHFrames.push_back(FunctionEHFrameInfo(FunctionEHName, SubprogramCount,
+ EHFrames.push_back(FunctionEHFrameInfo(FunctionEHSym, SubprogramCount,
MMI->getPersonalityIndex(),
MF->getFrameInfo()->hasCalls(),
!MMI->getLandingPads().empty(),
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.h b/lib/CodeGen/AsmPrinter/DwarfException.h
index aa01c5b..3921e91 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.h
+++ b/lib/CodeGen/AsmPrinter/DwarfException.h
@@ -32,21 +32,21 @@ class raw_ostream;
//===----------------------------------------------------------------------===//
/// DwarfException - Emits Dwarf exception handling directives.
///
-class DwarfException : public Dwarf {
+class DwarfException : public DwarfPrinter {
struct FunctionEHFrameInfo {
- std::string FnName;
+ MCSymbol *FunctionEHSym; // L_foo.eh
unsigned Number;
unsigned PersonalityIndex;
bool hasCalls;
bool hasLandingPads;
std::vector<MachineMove> Moves;
- const Function * function;
+ const Function *function;
- FunctionEHFrameInfo(const std::string &FN, unsigned Num, unsigned P,
+ FunctionEHFrameInfo(MCSymbol *EHSym, unsigned Num, unsigned P,
bool hC, bool hL,
const std::vector<MachineMove> &M,
const Function *f):
- FnName(FN), Number(Num), PersonalityIndex(P),
+ FunctionEHSym(EHSym), Number(Num), PersonalityIndex(P),
hasCalls(hC), hasLandingPads(hL), Moves(M), function (f) { }
};
diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
index 20b959b..d204bba 100644
--- a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
@@ -18,21 +18,22 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/ADT/StringExtras.h"
using namespace llvm;
-Dwarf::Dwarf(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T,
- const char *flavor)
+DwarfPrinter::DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T,
+ const char *flavor)
: O(OS), Asm(A), MAI(T), TD(Asm->TM.getTargetData()),
RI(Asm->TM.getRegisterInfo()), M(NULL), MF(NULL), MMI(NULL),
SubprogramCount(0), Flavor(flavor), SetCounter(1) {}
-void Dwarf::PrintRelDirective(bool Force32Bit, bool isInSection) const {
+void DwarfPrinter::PrintRelDirective(bool Force32Bit, bool isInSection) const {
if (isInSection && MAI->getDwarfSectionOffsetDirective())
O << MAI->getDwarfSectionOffsetDirective();
else if (Force32Bit || TD->getPointerSize() == sizeof(int32_t))
@@ -41,14 +42,125 @@ void Dwarf::PrintRelDirective(bool Force32Bit, bool isInSection) const {
O << MAI->getData64bitsDirective();
}
+/// EOL - Print a newline character to asm stream. If a comment is present
+/// then it will be printed first. Comments should not contain '\n'.
+void DwarfPrinter::EOL(const Twine &Comment) const {
+ if (Asm->VerboseAsm && !Comment.isTriviallyEmpty()) {
+ Asm->O.PadToColumn(MAI->getCommentColumn());
+ Asm->O << Asm->MAI->getCommentString() << ' ' << Comment;
+ }
+ Asm->O << '\n';
+}
+
+static const char *DecodeDWARFEncoding(unsigned Encoding) {
+ switch (Encoding) {
+ case dwarf::DW_EH_PE_absptr: return "absptr";
+ case dwarf::DW_EH_PE_omit: return "omit";
+ case dwarf::DW_EH_PE_pcrel: return "pcrel";
+ case dwarf::DW_EH_PE_udata4: return "udata4";
+ case dwarf::DW_EH_PE_udata8: return "udata8";
+ case dwarf::DW_EH_PE_sdata4: return "sdata4";
+ case dwarf::DW_EH_PE_sdata8: return "sdata8";
+ case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4: return "pcrel udata4";
+ case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4: return "pcrel sdata4";
+ case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8: return "pcrel udata8";
+ case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8: return "pcrel sdata8";
+ case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata4:
+ return "indirect pcrel udata4";
+ case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata4:
+ return "indirect pcrel sdata4";
+ case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata8:
+ return "indirect pcrel udata8";
+ case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata8:
+ return "indirect pcrel sdata8";
+ }
+
+ return "<unknown encoding>";
+}
+
+/// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
+/// encoding. If verbose assembly output is enabled, we output comments
+/// describing the encoding. Desc is an optional string saying what the
+/// encoding is specifying (e.g. "LSDA").
+void DwarfPrinter::EmitEncodingByte(unsigned Val, const char *Desc) {
+ if (Asm->VerboseAsm) {
+ if (Desc != 0)
+ Asm->OutStreamer.AddComment(Twine(Desc)+" Encoding = " +
+ Twine(DecodeDWARFEncoding(Val)));
+ else
+ Asm->OutStreamer.AddComment(Twine("Encoding = ") +
+ DecodeDWARFEncoding(Val));
+ }
+
+ Asm->OutStreamer.EmitIntValue(Val, 1, 0/*addrspace*/);
+}
+
+/// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value.
+void DwarfPrinter::EmitCFAByte(unsigned Val) {
+ if (Asm->VerboseAsm) {
+ if (Val >= dwarf::DW_CFA_offset && Val < dwarf::DW_CFA_offset+64)
+ Asm->OutStreamer.AddComment("DW_CFA_offset + Reg (" +
+ Twine(Val-dwarf::DW_CFA_offset) + ")");
+ else
+ Asm->OutStreamer.AddComment(dwarf::CallFrameString(Val));
+ }
+ Asm->OutStreamer.EmitIntValue(Val, 1, 0/*addrspace*/);
+}
+
+/// EmitSLEB128 - emit the specified signed leb128 value.
+void DwarfPrinter::EmitSLEB128(int Value, const char *Desc) const {
+ if (Asm->VerboseAsm && Desc)
+ Asm->OutStreamer.AddComment(Desc);
+
+ if (MAI->hasLEB128()) {
+ O << "\t.sleb128\t" << Value;
+ Asm->OutStreamer.AddBlankLine();
+ return;
+ }
+
+ // If we don't have .sleb128, emit as .bytes.
+ int Sign = Value >> (8 * sizeof(Value) - 1);
+ bool IsMore;
+
+ do {
+ unsigned char Byte = static_cast<unsigned char>(Value & 0x7f);
+ Value >>= 7;
+ IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
+ if (IsMore) Byte |= 0x80;
+
+ Asm->OutStreamer.EmitIntValue(Byte, 1, /*addrspace*/0);
+ } while (IsMore);
+}
+
+/// EmitULEB128 - emit the specified signed leb128 value.
+void DwarfPrinter::EmitULEB128(unsigned Value, const char *Desc) const {
+ if (Asm->VerboseAsm && Desc)
+ Asm->OutStreamer.AddComment(Desc);
+
+ if (MAI->hasLEB128()) {
+ O << "\t.uleb128\t" << Value;
+ Asm->OutStreamer.AddBlankLine();
+ return;
+ }
+
+ // If we don't have .uleb128, emit as .bytes.
+ do {
+ unsigned char Byte = static_cast<unsigned char>(Value & 0x7f);
+ Value >>= 7;
+ if (Value) Byte |= 0x80;
+ Asm->OutStreamer.EmitIntValue(Byte, 1, /*addrspace*/0);
+ } while (Value);
+}
+
+
/// PrintLabelName - Print label name in form used by Dwarf writer.
///
-void Dwarf::PrintLabelName(const char *Tag, unsigned Number) const {
+void DwarfPrinter::PrintLabelName(const char *Tag, unsigned Number) const {
O << MAI->getPrivateGlobalPrefix() << Tag;
if (Number) O << Number;
}
-void Dwarf::PrintLabelName(const char *Tag, unsigned Number,
- const char *Suffix) const {
+void DwarfPrinter::PrintLabelName(const char *Tag, unsigned Number,
+ const char *Suffix) const {
O << MAI->getPrivateGlobalPrefix() << Tag;
if (Number) O << Number;
O << Suffix;
@@ -56,32 +168,39 @@ void Dwarf::PrintLabelName(const char *Tag, unsigned Number,
/// EmitLabel - Emit location label for internal use by Dwarf.
///
-void Dwarf::EmitLabel(const char *Tag, unsigned Number) const {
+void DwarfPrinter::EmitLabel(const char *Tag, unsigned Number) const {
PrintLabelName(Tag, Number);
O << ":\n";
}
/// EmitReference - Emit a reference to a label.
///
-void Dwarf::EmitReference(const char *Tag, unsigned Number,
- bool IsPCRelative, bool Force32Bit) const {
+void DwarfPrinter::EmitReference(const char *Tag, unsigned Number,
+ bool IsPCRelative, bool Force32Bit) const {
PrintRelDirective(Force32Bit);
PrintLabelName(Tag, Number);
if (IsPCRelative) O << "-" << MAI->getPCSymbol();
}
-void Dwarf::EmitReference(const std::string &Name, bool IsPCRelative,
- bool Force32Bit) const {
+void DwarfPrinter::EmitReference(const std::string &Name, bool IsPCRelative,
+ bool Force32Bit) const {
PrintRelDirective(Force32Bit);
O << Name;
if (IsPCRelative) O << "-" << MAI->getPCSymbol();
}
+void DwarfPrinter::EmitReference(const MCSymbol *Sym, bool IsPCRelative,
+ bool Force32Bit) const {
+ PrintRelDirective(Force32Bit);
+ O << *Sym;
+ if (IsPCRelative) O << "-" << MAI->getPCSymbol();
+}
+
/// EmitDifference - Emit the difference between two labels. Some assemblers do
/// not behave with absolute expressions with data directives, so there is an
/// option (needsSet) to use an intermediary set expression.
-void Dwarf::EmitDifference(const char *TagHi, unsigned NumberHi,
- const char *TagLo, unsigned NumberLo,
- bool IsSmall) {
+void DwarfPrinter::EmitDifference(const char *TagHi, unsigned NumberHi,
+ const char *TagLo, unsigned NumberLo,
+ bool IsSmall) {
if (MAI->needsSet()) {
O << "\t.set\t";
PrintLabelName("set", SetCounter, Flavor);
@@ -102,10 +221,11 @@ void Dwarf::EmitDifference(const char *TagHi, unsigned NumberHi,
}
}
-void Dwarf::EmitSectionOffset(const char* Label, const char* Section,
- unsigned LabelNumber, unsigned SectionNumber,
- bool IsSmall, bool isEH,
- bool useSet) {
+void DwarfPrinter::EmitSectionOffset(const char* Label, const char* Section,
+ unsigned LabelNumber,
+ unsigned SectionNumber,
+ bool IsSmall, bool isEH,
+ bool useSet) {
bool printAbsolute = false;
if (isEH)
printAbsolute = MAI->isAbsoluteEHSectionOffsets();
@@ -140,8 +260,9 @@ void Dwarf::EmitSectionOffset(const char* Label, const char* Section,
/// EmitFrameMoves - Emit frame instructions to describe the layout of the
/// frame.
-void Dwarf::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
- const std::vector<MachineMove> &Moves, bool isEH) {
+void DwarfPrinter::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
+ const std::vector<MachineMove> &Moves,
+ bool isEH) {
int stackGrowth =
Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
TargetFrameInfo::StackGrowsUp ?
@@ -164,10 +285,9 @@ void Dwarf::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
// Advance row if new location.
if (BaseLabel && LabelID && (BaseLabelID != LabelID || !IsLocal)) {
- Asm->EmitInt8(dwarf::DW_CFA_advance_loc4);
- Asm->EOL("DW_CFA_advance_loc4");
+ EmitCFAByte(dwarf::DW_CFA_advance_loc4);
EmitDifference("label", LabelID, BaseLabel, BaseLabelID, true);
- Asm->EOL();
+ Asm->O << '\n';
BaseLabelID = LabelID;
BaseLabel = "label";
@@ -178,29 +298,22 @@ void Dwarf::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
if (!Src.isReg()) {
if (Src.getReg() == MachineLocation::VirtualFP) {
- Asm->EmitInt8(dwarf::DW_CFA_def_cfa_offset);
- Asm->EOL("DW_CFA_def_cfa_offset");
+ EmitCFAByte(dwarf::DW_CFA_def_cfa_offset);
} else {
- Asm->EmitInt8(dwarf::DW_CFA_def_cfa);
- Asm->EOL("DW_CFA_def_cfa");
- Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Src.getReg(), isEH));
- Asm->EOL("Register");
+ EmitCFAByte(dwarf::DW_CFA_def_cfa);
+ EmitULEB128(RI->getDwarfRegNum(Src.getReg(), isEH), "Register");
}
int Offset = -Src.getOffset();
-
- Asm->EmitULEB128Bytes(Offset);
- Asm->EOL("Offset");
+ EmitULEB128(Offset, "Offset");
} else {
llvm_unreachable("Machine move not supported yet.");
}
} else if (Src.isReg() &&
Src.getReg() == MachineLocation::VirtualFP) {
if (Dst.isReg()) {
- Asm->EmitInt8(dwarf::DW_CFA_def_cfa_register);
- Asm->EOL("DW_CFA_def_cfa_register");
- Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Dst.getReg(), isEH));
- Asm->EOL("Register");
+ EmitCFAByte(dwarf::DW_CFA_def_cfa_register);
+ EmitULEB128(RI->getDwarfRegNum(Dst.getReg(), isEH), "Register");
} else {
llvm_unreachable("Machine move not supported yet.");
}
@@ -209,27 +322,16 @@ void Dwarf::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
int Offset = Dst.getOffset() / stackGrowth;
if (Offset < 0) {
- Asm->EmitInt8(dwarf::DW_CFA_offset_extended_sf);
- Asm->EOL("DW_CFA_offset_extended_sf");
- Asm->EmitULEB128Bytes(Reg);
- Asm->EOL("Reg");
- Asm->EmitSLEB128Bytes(Offset);
- Asm->EOL("Offset");
+ EmitCFAByte(dwarf::DW_CFA_offset_extended_sf);
+ EmitULEB128(Reg, "Reg");
+ EmitSLEB128(Offset, "Offset");
} else if (Reg < 64) {
- Asm->EmitInt8(dwarf::DW_CFA_offset + Reg);
- if (Asm->isVerbose())
- Asm->EOL("DW_CFA_offset + Reg (" + utostr(Reg) + ")");
- else
- Asm->EOL();
- Asm->EmitULEB128Bytes(Offset);
- Asm->EOL("Offset");
+ EmitCFAByte(dwarf::DW_CFA_offset + Reg);
+ EmitULEB128(Offset, "Offset");
} else {
- Asm->EmitInt8(dwarf::DW_CFA_offset_extended);
- Asm->EOL("DW_CFA_offset_extended");
- Asm->EmitULEB128Bytes(Reg);
- Asm->EOL("Reg");
- Asm->EmitULEB128Bytes(Offset);
- Asm->EOL("Offset");
+ EmitCFAByte(dwarf::DW_CFA_offset_extended);
+ EmitULEB128(Reg, "Reg");
+ EmitULEB128(Offset, "Offset");
}
}
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.h b/lib/CodeGen/AsmPrinter/DwarfPrinter.h
index dedd695..86fe2ab 100644
--- a/lib/CodeGen/AsmPrinter/DwarfPrinter.h
+++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.h
@@ -17,135 +17,149 @@
#include "DwarfLabel.h"
#include "llvm/CodeGen/MachineLocation.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/FormattedStream.h"
#include <vector>
namespace llvm {
- class AsmPrinter;
- class MachineFunction;
- class MachineModuleInfo;
- class Module;
- class MCAsmInfo;
- class TargetData;
- class TargetRegisterInfo;
-
- class Dwarf {
- protected:
- //===-------------------------------------------------------------==---===//
- // Core attributes used by the DWARF printer.
- //
-
- /// O - Stream to .s file.
- ///
- raw_ostream &O;
-
- /// Asm - Target of Dwarf emission.
- ///
- AsmPrinter *Asm;
-
- /// MAI - Target asm information.
- ///
- const MCAsmInfo *MAI;
-
- /// TD - Target data.
- ///
- const TargetData *TD;
-
- /// RI - Register Information.
- ///
- const TargetRegisterInfo *RI;
-
- /// M - Current module.
- ///
- Module *M;
-
- /// MF - Current machine function.
- ///
- MachineFunction *MF;
-
- /// MMI - Collected machine module information.
- ///
- MachineModuleInfo *MMI;
-
- /// SubprogramCount - The running count of functions being compiled.
- ///
- unsigned SubprogramCount;
-
- /// Flavor - A unique string indicating what dwarf producer this is, used to
- /// unique labels.
- ///
- const char * const Flavor;
-
- /// SetCounter - A unique number for each '.set' directive.
- ///
- unsigned SetCounter;
-
- Dwarf(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T,
- const char *flavor);
- public:
- //===------------------------------------------------------------------===//
- // Accessors.
- //
- const AsmPrinter *getAsm() const { return Asm; }
- MachineModuleInfo *getMMI() const { return MMI; }
- const MCAsmInfo *getMCAsmInfo() const { return MAI; }
- const TargetData *getTargetData() const { return TD; }
-
- void PrintRelDirective(bool Force32Bit = false,
- bool isInSection = false) const;
-
-
- /// PrintLabelName - Print label name in form used by Dwarf writer.
- ///
- void PrintLabelName(const DWLabel &Label) const {
- PrintLabelName(Label.getTag(), Label.getNumber());
- }
- void PrintLabelName(const char *Tag, unsigned Number) const;
- void PrintLabelName(const char *Tag, unsigned Number,
- const char *Suffix) const;
-
- /// EmitLabel - Emit location label for internal use by Dwarf.
- ///
- void EmitLabel(const DWLabel &Label) const {
- EmitLabel(Label.getTag(), Label.getNumber());
- }
- void EmitLabel(const char *Tag, unsigned Number) const;
-
- /// EmitReference - Emit a reference to a label.
- ///
- void EmitReference(const DWLabel &Label, bool IsPCRelative = false,
- bool Force32Bit = false) const {
- EmitReference(Label.getTag(), Label.getNumber(),
- IsPCRelative, Force32Bit);
- }
- void EmitReference(const char *Tag, unsigned Number,
- bool IsPCRelative = false,
- bool Force32Bit = false) const;
- void EmitReference(const std::string &Name, bool IsPCRelative = false,
- bool Force32Bit = false) const;
-
- /// EmitDifference - Emit the difference between two labels. Some
- /// assemblers do not behave with absolute expressions with data directives,
- /// so there is an option (needsSet) to use an intermediary set expression.
- void EmitDifference(const DWLabel &LabelHi, const DWLabel &LabelLo,
- bool IsSmall = false) {
- EmitDifference(LabelHi.getTag(), LabelHi.getNumber(),
- LabelLo.getTag(), LabelLo.getNumber(),
- IsSmall);
- }
- void EmitDifference(const char *TagHi, unsigned NumberHi,
- const char *TagLo, unsigned NumberLo,
- bool IsSmall = false);
-
- void EmitSectionOffset(const char* Label, const char* Section,
- unsigned LabelNumber, unsigned SectionNumber,
- bool IsSmall = false, bool isEH = false,
- bool useSet = true);
-
- /// EmitFrameMoves - Emit frame instructions to describe the layout of the
- /// frame.
- void EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
- const std::vector<MachineMove> &Moves, bool isEH);
+class AsmPrinter;
+class MachineFunction;
+class MachineModuleInfo;
+class Module;
+class MCAsmInfo;
+class TargetData;
+class TargetRegisterInfo;
+class MCSymbol;
+class Twine;
+
+class DwarfPrinter {
+protected:
+ //===-------------------------------------------------------------==---===//
+ // Core attributes used by the DWARF printer.
+ //
+
+ /// O - Stream to .s file.
+ raw_ostream &O;
+
+ /// Asm - Target of Dwarf emission.
+ AsmPrinter *Asm;
+
+ /// MAI - Target asm information.
+ const MCAsmInfo *MAI;
+
+ /// TD - Target data.
+ const TargetData *TD;
+
+ /// RI - Register Information.
+ const TargetRegisterInfo *RI;
+
+ /// M - Current module.
+ Module *M;
+
+ /// MF - Current machine function.
+ MachineFunction *MF;
+
+ /// MMI - Collected machine module information.
+ MachineModuleInfo *MMI;
+
+ /// SubprogramCount - The running count of functions being compiled.
+ unsigned SubprogramCount;
+
+ /// Flavor - A unique string indicating what dwarf producer this is, used to
+ /// unique labels.
+ const char * const Flavor;
+
+ /// SetCounter - A unique number for each '.set' directive.
+ unsigned SetCounter;
+
+ DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T,
+ const char *flavor);
+public:
+
+ //===------------------------------------------------------------------===//
+ // Accessors.
+ //
+ const AsmPrinter *getAsm() const { return Asm; }
+ MachineModuleInfo *getMMI() const { return MMI; }
+ const MCAsmInfo *getMCAsmInfo() const { return MAI; }
+ const TargetData *getTargetData() const { return TD; }
+
+ void PrintRelDirective(bool Force32Bit = false,
+ bool isInSection = false) const;
+
+ /// EOL - Print a newline character to asm stream. If a comment is present
+ /// then it will be printed first. Comments should not contain '\n'.
+ void EOL(const Twine &Comment) const;
+
+ /// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
+ /// encoding. If verbose assembly output is enabled, we output comments
+ /// describing the encoding. Desc is a string saying what the encoding is
+ /// specifying (e.g. "LSDA").
+ void EmitEncodingByte(unsigned Val, const char *Desc);
+
+ /// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value.
+ void EmitCFAByte(unsigned Val);
+
+
+ /// EmitSLEB128 - emit the specified signed leb128 value.
+ void EmitSLEB128(int Value, const char *Desc) const;
+
+ /// EmitULEB128 - emit the specified unsigned leb128 value.
+ void EmitULEB128(unsigned Value, const char *Desc = 0) const;
+
+
+ /// PrintLabelName - Print label name in form used by Dwarf writer.
+ ///
+ void PrintLabelName(const DWLabel &Label) const {
+ PrintLabelName(Label.getTag(), Label.getNumber());
+ }
+ void PrintLabelName(const char *Tag, unsigned Number) const;
+ void PrintLabelName(const char *Tag, unsigned Number,
+ const char *Suffix) const;
+
+ /// EmitLabel - Emit location label for internal use by Dwarf.
+ ///
+ void EmitLabel(const DWLabel &Label) const {
+ EmitLabel(Label.getTag(), Label.getNumber());
+ }
+ void EmitLabel(const char *Tag, unsigned Number) const;
+
+ /// EmitReference - Emit a reference to a label.
+ ///
+ void EmitReference(const DWLabel &Label, bool IsPCRelative = false,
+ bool Force32Bit = false) const {
+ EmitReference(Label.getTag(), Label.getNumber(),
+ IsPCRelative, Force32Bit);
+ }
+ void EmitReference(const char *Tag, unsigned Number,
+ bool IsPCRelative = false,
+ bool Force32Bit = false) const;
+ void EmitReference(const std::string &Name, bool IsPCRelative = false,
+ bool Force32Bit = false) const;
+ void EmitReference(const MCSymbol *Sym, bool IsPCRelative = false,
+ bool Force32Bit = false) const;
+
+ /// EmitDifference - Emit the difference between two labels. Some
+ /// assemblers do not behave with absolute expressions with data directives,
+ /// so there is an option (needsSet) to use an intermediary set expression.
+ void EmitDifference(const DWLabel &LabelHi, const DWLabel &LabelLo,
+ bool IsSmall = false) {
+ EmitDifference(LabelHi.getTag(), LabelHi.getNumber(),
+ LabelLo.getTag(), LabelLo.getNumber(),
+ IsSmall);
+ }
+ void EmitDifference(const char *TagHi, unsigned NumberHi,
+ const char *TagLo, unsigned NumberLo,
+ bool IsSmall = false);
+
+ void EmitSectionOffset(const char* Label, const char* Section,
+ unsigned LabelNumber, unsigned SectionNumber,
+ bool IsSmall = false, bool isEH = false,
+ bool useSet = true);
+
+ /// EmitFrameMoves - Emit frame instructions to describe the layout of the
+ /// frame.
+ void EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
+ const std::vector<MachineMove> &Moves, bool isEH);
};
} // end llvm namespace
diff --git a/lib/CodeGen/AsmPrinter/Makefile b/lib/CodeGen/AsmPrinter/Makefile
index 8f65d8d..b0071d0 100644
--- a/lib/CodeGen/AsmPrinter/Makefile
+++ b/lib/CodeGen/AsmPrinter/Makefile
@@ -1,4 +1,4 @@
-##===- lib/CodeGen/SelectionDAG/Makefile -------------------*- Makefile -*-===##
+##===- lib/CodeGen/AsmPrinter/Makefile ---------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
@@ -6,8 +6,9 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMAsmPrinter
-PARALLEL_DIRS =
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
index 9286ad5..3531ed6 100644
--- a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
@@ -21,7 +21,7 @@
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/FormattedStream.h"
using namespace llvm;
namespace {
@@ -105,8 +105,7 @@ void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP,
AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getDataSection());
EmitCamlGlobal(getModule(), OS, AP, MAI, "data_end");
- OS << AddressDirective << 0; // FIXME: Why does ocaml emit this??
- AP.EOL();
+ OS << AddressDirective << 0 << '\n'; // FIXME: Why does ocaml emit this??
AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getDataSection());
EmitCamlGlobal(getModule(), OS, AP, MAI, "frametable");
@@ -140,14 +139,11 @@ void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP,
}
OS << AddressDirective
- << MAI.getPrivateGlobalPrefix() << "label" << J->Num;
- AP.EOL("call return address");
+ << MAI.getPrivateGlobalPrefix() << "label" << J->Num << '\n';
AP.EmitInt16(FrameSize);
- AP.EOL("stack frame size");
AP.EmitInt16(LiveCount);
- AP.EOL("live root count");
for (GCFunctionInfo::live_iterator K = FI.live_begin(J),
KE = FI.live_end(J); K != KE; ++K) {
@@ -155,8 +151,7 @@ void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP,
"GC root stack offset is outside of fixed stack frame and out "
"of range for ocaml GC!");
- OS << "\t.word\t" << K->StackOffset;
- AP.EOL("stack offset");
+ AP.EmitInt32(K->StackOffset);
}
AP.EmitAlignment(AddressAlignLog);
diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt
index 6bc808c..17072d3 100644
--- a/lib/CodeGen/CMakeLists.txt
+++ b/lib/CodeGen/CMakeLists.txt
@@ -21,7 +21,6 @@ add_llvm_library(LLVMCodeGen
LiveStackAnalysis.cpp
LiveVariables.cpp
LowerSubregs.cpp
- MachOCodeEmitter.cpp
MachOWriter.cpp
MachineBasicBlock.cpp
MachineDominators.cpp
@@ -38,7 +37,6 @@ add_llvm_library(LLVMCodeGen
MachineSSAUpdater.cpp
MachineSink.cpp
MachineVerifier.cpp
- MaxStackAlignment.cpp
ObjectCodeEmitter.cpp
OcamlGC.cpp
OptimizeExts.cpp
diff --git a/lib/CodeGen/DwarfEHPrepare.cpp b/lib/CodeGen/DwarfEHPrepare.cpp
index 9b516ed..39fc85e 100644
--- a/lib/CodeGen/DwarfEHPrepare.cpp
+++ b/lib/CodeGen/DwarfEHPrepare.cpp
@@ -21,6 +21,7 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
@@ -114,6 +115,9 @@ FunctionPass *llvm::createDwarfEHPass(const TargetLowering *tli, bool fast) {
bool DwarfEHPrepare::NormalizeLandingPads() {
bool Changed = false;
+ const MCAsmInfo *MAI = TLI->getTargetMachine().getMCAsmInfo();
+ bool usingSjLjEH = MAI->getExceptionHandlingType() == ExceptionHandling::SjLj;
+
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
TerminatorInst *TI = I->getTerminator();
if (!isa<InvokeInst>(TI))
@@ -125,9 +129,18 @@ bool DwarfEHPrepare::NormalizeLandingPads() {
// Check that only invoke unwind edges end at the landing pad.
bool OnlyUnwoundTo = true;
+ bool SwitchOK = usingSjLjEH;
for (pred_iterator PI = pred_begin(LPad), PE = pred_end(LPad);
PI != PE; ++PI) {
TerminatorInst *PT = (*PI)->getTerminator();
+ // The SjLj dispatch block uses a switch instruction. This is effectively
+ // an unwind edge, so we can disregard it here. There will only ever
+ // be one dispatch, however, so if there are multiple switches, one
+ // of them truly is a normal edge, not an unwind edge.
+ if (SwitchOK && isa<SwitchInst>(PT)) {
+ SwitchOK = false;
+ continue;
+ }
if (!isa<InvokeInst>(PT) || LPad == PT->getSuccessor(0)) {
OnlyUnwoundTo = false;
break;
diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp
index 5e5f589..de45e09 100644
--- a/lib/CodeGen/ELFWriter.cpp
+++ b/lib/CodeGen/ELFWriter.cpp
@@ -45,6 +45,7 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetELFWriterInfo.h"
#include "llvm/Target/TargetLowering.h"
@@ -52,9 +53,8 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/raw_ostream.h"
-
+#include "llvm/ADT/SmallString.h"
using namespace llvm;
char ELFWriter::ID = 0;
@@ -119,7 +119,7 @@ bool ELFWriter::doInitialization(Module &M) {
// Initialize TargetLoweringObjectFile.
const_cast<TargetLoweringObjectFile&>(TLOF).Initialize(OutContext, TM);
- Mang = new Mangler(M);
+ Mang = new Mangler(*MAI);
// ELF Header
// ----------
@@ -703,10 +703,6 @@ bool ELFWriter::doFinalization(Module &M) {
I != E; ++I)
SymbolList.push_back(ELFSym::getExtSym(*I));
- // Emit non-executable stack note
- if (MAI->getNonexecutableStackDirective())
- getNonExecStackSection();
-
// Emit a symbol for each section created until now, skip null section
for (unsigned i = 1, e = SectionList.size(); i < e; ++i) {
ELFSection &ES = *SectionList[i];
@@ -906,9 +902,11 @@ void ELFWriter::EmitStringTable(const std::string &ModuleName) {
ELFSym &Sym = *(*I);
std::string Name;
- if (Sym.isGlobalValue())
- Name.append(Mang->getMangledName(Sym.getGlobalValue()));
- else if (Sym.isExternalSym())
+ if (Sym.isGlobalValue()) {
+ SmallString<40> NameStr;
+ Mang->getNameWithPrefix(NameStr, Sym.getGlobalValue(), false);
+ Name.append(NameStr.begin(), NameStr.end());
+ } else if (Sym.isExternalSym())
Name.append(Sym.getExternalSymbol());
else if (Sym.isFileType())
Name.append(ModuleName);
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
index 2b5fd2c..837e184 100644
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -17,6 +17,7 @@
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/FileWriters.h"
#include "llvm/CodeGen/GCStrategy.h"
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/Target/TargetOptions.h"
@@ -38,6 +39,8 @@ static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden,
cl::desc("Disable branch folding"));
static cl::opt<bool> DisableTailDuplicate("disable-tail-duplicate", cl::Hidden,
cl::desc("Disable tail duplication"));
+static cl::opt<bool> DisableEarlyTailDup("disable-early-taildup", cl::Hidden,
+ cl::desc("Disable pre-register allocation tail duplication"));
static cl::opt<bool> DisableCodePlace("disable-code-place", cl::Hidden,
cl::desc("Disable code placement"));
static cl::opt<bool> DisableSSC("disable-ssc", cl::Hidden,
@@ -76,9 +79,6 @@ EnableFastISelOption("fast-isel", cl::Hidden,
static cl::opt<bool> EnableSplitGEPGVN("split-gep-gvn", cl::Hidden,
cl::desc("Split GEPs and run no-load GVN"));
-static cl::opt<bool> PreAllocTailDup("pre-regalloc-taildup", cl::Hidden,
- cl::desc("Pre-register allocation tail duplication"));
-
LLVMTargetMachine::LLVMTargetMachine(const Target &T,
const std::string &TargetTriple)
: TargetMachine(T) {
@@ -115,12 +115,11 @@ LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
return FileModel::Error;
return FileModel::AsmFile;
case TargetMachine::ObjectFile:
- if (getMachOWriterInfo())
+ if (!addObjectFileEmitter(PM, OptLevel, Out))
return FileModel::MachOFile;
else if (getELFWriterInfo())
- return FileModel::ElfFile;
+ return FileModel::ElfFile;
}
-
return FileModel::Error;
}
@@ -137,6 +136,17 @@ bool LLVMTargetMachine::addAssemblyEmitter(PassManagerBase &PM,
return false;
}
+bool LLVMTargetMachine::addObjectFileEmitter(PassManagerBase &PM,
+ CodeGenOpt::Level OptLevel,
+ formatted_raw_ostream &Out) {
+ MCCodeEmitter *Emitter = getTarget().createCodeEmitter(*this);
+ if (!Emitter)
+ return true;
+
+ PM.add(createMachOWriter(Out, *this, getMCAsmInfo(), Emitter));
+ return false;
+}
+
/// addPassesToEmitFileFinish - If the passes to emit the specified file had to
/// be split up (e.g., to add an object writer pass), this method can be used to
/// finish up adding passes to emit the file, if necessary.
@@ -340,8 +350,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
}
// Pre-ra tail duplication.
- if (OptLevel != CodeGenOpt::None &&
- !DisableTailDuplicate && PreAllocTailDup) {
+ if (OptLevel != CodeGenOpt::None && !DisableEarlyTailDup) {
PM.add(createTailDuplicatePass(true));
printAndVerify(PM, "After Pre-RegAlloc TailDuplicate",
/* allowDoubleDefs= */ true);
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index e0e2ec8..8746bf9 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -140,7 +140,10 @@ void LiveIntervals::printInstrs(raw_ostream &OS) const {
<< ":\t\t# derived from " << mbbi->getName() << "\n";
for (MachineBasicBlock::iterator mii = mbbi->begin(),
mie = mbbi->end(); mii != mie; ++mii) {
- OS << getInstructionIndex(mii) << '\t' << *mii;
+ if (mii->getOpcode()==TargetInstrInfo::DEBUG_VALUE)
+ OS << SlotIndex::getEmptyKey() << '\t' << *mii;
+ else
+ OS << getInstructionIndex(mii) << '\t' << *mii;
}
}
}
@@ -672,8 +675,6 @@ void LiveIntervals::computeIntervals() {
SlotIndex MIIndex = getMBBStartIdx(MBB);
DEBUG(dbgs() << MBB->getName() << ":\n");
- MachineBasicBlock::iterator MI = MBB->begin(), miEnd = MBB->end();
-
// Create intervals for live-ins to this BB first.
for (MachineBasicBlock::const_livein_iterator LI = MBB->livein_begin(),
LE = MBB->livein_end(); LI != LE; ++LI) {
@@ -689,8 +690,11 @@ void LiveIntervals::computeIntervals() {
if (getInstructionFromIndex(MIIndex) == 0)
MIIndex = indexes_->getNextNonNullIndex(MIIndex);
- for (; MI != miEnd; ++MI) {
+ for (MachineBasicBlock::iterator MI = MBB->begin(), miEnd = MBB->end();
+ MI != miEnd; ++MI) {
DEBUG(dbgs() << MIIndex << "\t" << *MI);
+ if (MI->getOpcode()==TargetInstrInfo::DEBUG_VALUE)
+ continue;
// Handle defs.
for (int i = MI->getNumOperands() - 1; i >= 0; --i) {
diff --git a/lib/CodeGen/MachO.h b/lib/CodeGen/MachO.h
deleted file mode 100644
index f2b40fe..0000000
--- a/lib/CodeGen/MachO.h
+++ /dev/null
@@ -1,412 +0,0 @@
-//=== MachO.h - Mach-O structures and constants -----------------*- 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 MachO .
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef MACHO_H
-#define MACHO_H
-
-#include "llvm/CodeGen/BinaryObject.h"
-#include <string>
-#include <vector>
-
-namespace llvm {
-
-class GlobalValue;
-class MCAsmInfo;
-
-/// MachOSym - This struct contains information about each symbol that is
-/// added to logical symbol table for the module. This is eventually
-/// turned into a real symbol table in the file.
-struct MachOSym {
- const GlobalValue *GV; // The global value this corresponds to.
- std::string GVName; // The mangled name of the global value.
- uint32_t n_strx; // index into the string table
- uint8_t n_type; // type flag
- uint8_t n_sect; // section number or NO_SECT
- int16_t n_desc; // see <mach-o/stab.h>
- uint64_t n_value; // value for this symbol (or stab offset)
-
- // Constants for the n_sect field
- // see <mach-o/nlist.h>
- enum { NO_SECT = 0 }; // symbol is not in any section
-
- // Constants for the n_type field
- // see <mach-o/nlist.h>
- enum { N_UNDF = 0x0, // undefined, n_sect == NO_SECT
- N_ABS = 0x2, // absolute, n_sect == NO_SECT
- N_SECT = 0xe, // defined in section number n_sect
- N_PBUD = 0xc, // prebound undefined (defined in a dylib)
- N_INDR = 0xa // indirect
- };
- // The following bits are OR'd into the types above. For example, a type
- // of 0x0f would be an external N_SECT symbol (0x0e | 0x01).
- enum { N_EXT = 0x01, // external symbol bit
- N_PEXT = 0x10 // private external symbol bit
- };
-
- // Constants for the n_desc field
- // see <mach-o/loader.h>
- enum { REFERENCE_FLAG_UNDEFINED_NON_LAZY = 0,
- REFERENCE_FLAG_UNDEFINED_LAZY = 1,
- REFERENCE_FLAG_DEFINED = 2,
- REFERENCE_FLAG_PRIVATE_DEFINED = 3,
- REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY = 4,
- REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY = 5
- };
- enum { N_NO_DEAD_STRIP = 0x0020, // symbol is not to be dead stripped
- N_WEAK_REF = 0x0040, // symbol is weak referenced
- N_WEAK_DEF = 0x0080 // coalesced symbol is a weak definition
- };
-
- MachOSym(const GlobalValue *gv, std::string name, uint8_t sect,
- const MCAsmInfo *MAI);
-
- struct SymCmp {
- // FIXME: this does not appear to be sorting 'f' after 'F'
- bool operator()(const MachOSym &LHS, const MachOSym &RHS) {
- return LHS.GVName < RHS.GVName;
- }
- };
-
-
- /// PartitionByLocal - Simple boolean predicate that returns true if Sym is
- /// a local symbol rather than an external symbol.
-
- static inline bool PartitionByLocal(const MachOSym &Sym) {
- return (Sym.n_type & (MachOSym::N_EXT | MachOSym::N_PEXT)) == 0;
- }
-
- /// PartitionByDefined - Simple boolean predicate that returns true if Sym is
- /// defined in this module.
-
- static inline bool PartitionByDefined(const MachOSym &Sym) {
- // FIXME: Do N_ABS or N_INDR count as defined?
- return (Sym.n_type & MachOSym::N_SECT) == MachOSym::N_SECT;
- }
-
-}; // end struct MachOSym
-
-/// MachOHeader - This struct contains the header information about a
-/// specific architecture type/subtype pair that is emitted to the file.
-
-struct MachOHeader {
- uint32_t magic; // mach magic number identifier
- uint32_t filetype; // type of file
- uint32_t ncmds; // number of load commands
- uint32_t sizeofcmds; // the size of all the load commands
- uint32_t flags; // flags
- uint32_t reserved; // 64-bit only
-
- /// HeaderData - The actual data for the header which we are building
- /// up for emission to the file.
- std::vector<unsigned char> HeaderData;
-
- // Constants for the filetype field
- // see <mach-o/loader.h> for additional info on the various types
- enum { MH_OBJECT = 1, // relocatable object file
- MH_EXECUTE = 2, // demand paged executable file
- MH_FVMLIB = 3, // fixed VM shared library file
- MH_CORE = 4, // core file
- MH_PRELOAD = 5, // preloaded executable file
- MH_DYLIB = 6, // dynamically bound shared library
- MH_DYLINKER = 7, // dynamic link editor
- MH_BUNDLE = 8, // dynamically bound bundle file
- MH_DYLIB_STUB = 9, // shared library stub for static linking only
- MH_DSYM = 10 // companion file wiht only debug sections
- };
-
- // Constants for the flags field
- enum { MH_NOUNDEFS = 1 << 0,
- // the object file has no undefined references
- MH_INCRLINK = 1 << 1,
- // the object file is the output of an incremental link against
- // a base file and cannot be link edited again
- MH_DYLDLINK = 1 << 2,
- // the object file is input for the dynamic linker and cannot be
- // statically link edited again.
- MH_BINDATLOAD = 1 << 3,
- // the object file's undefined references are bound by the
- // dynamic linker when loaded.
- MH_PREBOUND = 1 << 4,
- // the file has its dynamic undefined references prebound
- MH_SPLIT_SEGS = 1 << 5,
- // the file has its read-only and read-write segments split
- // see <mach/shared_memory_server.h>
- MH_LAZY_INIT = 1 << 6,
- // the shared library init routine is to be run lazily via
- // catching memory faults to its writable segments (obsolete)
- MH_TWOLEVEL = 1 << 7,
- // the image is using two-level namespace bindings
- MH_FORCE_FLAT = 1 << 8,
- // the executable is forcing all images to use flat namespace
- // bindings.
- MH_NOMULTIDEFS = 1 << 8,
- // this umbrella guarantees no multiple definitions of symbols
- // in its sub-images so the two-level namespace hints can
- // always be used.
- MH_NOFIXPREBINDING = 1 << 10,
- // do not have dyld notify the prebidning agent about this
- // executable.
- MH_PREBINDABLE = 1 << 11,
- // the binary is not prebound but can have its prebinding
- // redone. only used when MH_PREBOUND is not set.
- MH_ALLMODSBOUND = 1 << 12,
- // indicates that this binary binds to all two-level namespace
- // modules of its dependent libraries. Only used when
- // MH_PREBINDABLE and MH_TWOLEVEL are both set.
- MH_SUBSECTIONS_VIA_SYMBOLS = 1 << 13,
- // safe to divide up the sections into sub-sections via symbols
- // for dead code stripping.
- MH_CANONICAL = 1 << 14,
- // the binary has been canonicalized via the unprebind operation
- MH_WEAK_DEFINES = 1 << 15,
- // the final linked image contains external weak symbols
- MH_BINDS_TO_WEAK = 1 << 16,
- // the final linked image uses weak symbols
- MH_ALLOW_STACK_EXECUTION = 1 << 17
- // When this bit is set, all stacks in the task will be given
- // stack execution privilege. Only used in MH_EXECUTE filetype
- };
-
- MachOHeader() : magic(0), filetype(0), ncmds(0), sizeofcmds(0), flags(0),
- reserved(0) {}
-
- /// cmdSize - This routine returns the size of the MachOSection as written
- /// to disk, depending on whether the destination is a 64 bit Mach-O file.
- unsigned cmdSize(bool is64Bit) const {
- if (is64Bit)
- return 8 * sizeof(uint32_t);
- else
- return 7 * sizeof(uint32_t);
- }
-
- /// setMagic - This routine sets the appropriate value for the 'magic'
- /// field based on pointer size and endianness.
- void setMagic(bool isLittleEndian, bool is64Bit) {
- if (isLittleEndian)
- if (is64Bit) magic = 0xcffaedfe;
- else magic = 0xcefaedfe;
- else
- if (is64Bit) magic = 0xfeedfacf;
- else magic = 0xfeedface;
- }
-
-}; // end struct MachOHeader
-
-/// MachOSegment - This struct contains the necessary information to
-/// emit the load commands for each section in the file.
-struct MachOSegment {
- uint32_t cmd; // LC_SEGMENT or LC_SEGMENT_64
- uint32_t cmdsize; // Total size of this struct and section commands
- std::string segname; // segment name
- uint64_t vmaddr; // address of this segment
- uint64_t vmsize; // size of this segment, may be larger than filesize
- uint64_t fileoff; // offset in file
- uint64_t filesize; // amount to read from file
- uint32_t maxprot; // maximum VM protection
- uint32_t initprot; // initial VM protection
- uint32_t nsects; // number of sections in this segment
- uint32_t flags; // flags
-
- // The following constants are getting pulled in by one of the
- // system headers, which creates a neat clash with the enum.
-#if !defined(VM_PROT_NONE)
-#define VM_PROT_NONE 0x00
-#endif
-#if !defined(VM_PROT_READ)
-#define VM_PROT_READ 0x01
-#endif
-#if !defined(VM_PROT_WRITE)
-#define VM_PROT_WRITE 0x02
-#endif
-#if !defined(VM_PROT_EXECUTE)
-#define VM_PROT_EXECUTE 0x04
-#endif
-#if !defined(VM_PROT_ALL)
-#define VM_PROT_ALL 0x07
-#endif
-
- // Constants for the vm protection fields
- // see <mach-o/vm_prot.h>
- enum { SEG_VM_PROT_NONE = VM_PROT_NONE,
- SEG_VM_PROT_READ = VM_PROT_READ, // read permission
- SEG_VM_PROT_WRITE = VM_PROT_WRITE, // write permission
- SEG_VM_PROT_EXECUTE = VM_PROT_EXECUTE,
- SEG_VM_PROT_ALL = VM_PROT_ALL
- };
-
- // Constants for the cmd field
- // see <mach-o/loader.h>
- enum { LC_SEGMENT = 0x01, // segment of this file to be mapped
- LC_SEGMENT_64 = 0x19 // 64-bit segment of this file to be mapped
- };
-
- /// cmdSize - This routine returns the size of the MachOSection as written
- /// to disk, depending on whether the destination is a 64 bit Mach-O file.
- unsigned cmdSize(bool is64Bit) const {
- if (is64Bit)
- return 6 * sizeof(uint32_t) + 4 * sizeof(uint64_t) + 16;
- else
- return 10 * sizeof(uint32_t) + 16; // addresses only 32 bits
- }
-
- MachOSegment(const std::string &seg, bool is64Bit)
- : cmd(is64Bit ? LC_SEGMENT_64 : LC_SEGMENT), cmdsize(0), segname(seg),
- vmaddr(0), vmsize(0), fileoff(0), filesize(0), maxprot(VM_PROT_ALL),
- initprot(VM_PROT_ALL), nsects(0), flags(0) { }
-};
-
-/// MachOSection - This struct contains information about each section in a
-/// particular segment that is emitted to the file. This is eventually
-/// turned into the SectionCommand in the load command for a particlar
-/// segment.
-
-struct MachOSection : public BinaryObject {
- std::string sectname; // name of this section,
- std::string segname; // segment this section goes in
- uint64_t addr; // memory address of this section
- uint32_t offset; // file offset of this section
- uint32_t align; // section alignment (power of 2)
- uint32_t reloff; // file offset of relocation entries
- uint32_t nreloc; // number of relocation entries
- uint32_t flags; // flags (section type and attributes)
- uint32_t reserved1; // reserved (for offset or index)
- uint32_t reserved2; // reserved (for count or sizeof)
- uint32_t reserved3; // reserved (64 bit only)
-
- /// A unique number for this section, which will be used to match symbols
- /// to the correct section.
- uint32_t Index;
-
- /// RelocBuffer - A buffer to hold the mach-o relocations before we write
- /// them out at the appropriate location in the file.
- std::vector<unsigned char> RelocBuffer;
-
- // Constants for the section types (low 8 bits of flags field)
- // see <mach-o/loader.h>
- enum { S_REGULAR = 0,
- // regular section
- S_ZEROFILL = 1,
- // zero fill on demand section
- S_CSTRING_LITERALS = 2,
- // section with only literal C strings
- S_4BYTE_LITERALS = 3,
- // section with only 4 byte literals
- S_8BYTE_LITERALS = 4,
- // section with only 8 byte literals
- S_LITERAL_POINTERS = 5,
- // section with only pointers to literals
- S_NON_LAZY_SYMBOL_POINTERS = 6,
- // section with only non-lazy symbol pointers
- S_LAZY_SYMBOL_POINTERS = 7,
- // section with only lazy symbol pointers
- S_SYMBOL_STUBS = 8,
- // section with only symbol stubs
- // byte size of stub in the reserved2 field
- S_MOD_INIT_FUNC_POINTERS = 9,
- // section with only function pointers for initialization
- S_MOD_TERM_FUNC_POINTERS = 10,
- // section with only function pointers for termination
- S_COALESCED = 11,
- // section contains symbols that are coalesced
- S_GB_ZEROFILL = 12,
- // zero fill on demand section (that can be larger than 4GB)
- S_INTERPOSING = 13,
- // section with only pairs of function pointers for interposing
- S_16BYTE_LITERALS = 14
- // section with only 16 byte literals
- };
-
- // Constants for the section flags (high 24 bits of flags field)
- // see <mach-o/loader.h>
- enum { S_ATTR_PURE_INSTRUCTIONS = 1 << 31,
- // section contains only true machine instructions
- S_ATTR_NO_TOC = 1 << 30,
- // section contains coalesced symbols that are not to be in a
- // ranlib table of contents
- S_ATTR_STRIP_STATIC_SYMS = 1 << 29,
- // ok to strip static symbols in this section in files with the
- // MY_DYLDLINK flag
- S_ATTR_NO_DEAD_STRIP = 1 << 28,
- // no dead stripping
- S_ATTR_LIVE_SUPPORT = 1 << 27,
- // blocks are live if they reference live blocks
- S_ATTR_SELF_MODIFYING_CODE = 1 << 26,
- // used with i386 code stubs written on by dyld
- S_ATTR_DEBUG = 1 << 25,
- // a debug section
- S_ATTR_SOME_INSTRUCTIONS = 1 << 10,
- // section contains some machine instructions
- S_ATTR_EXT_RELOC = 1 << 9,
- // section has external relocation entries
- S_ATTR_LOC_RELOC = 1 << 8
- // section has local relocation entries
- };
-
- /// cmdSize - This routine returns the size of the MachOSection as written
- /// to disk, depending on whether the destination is a 64 bit Mach-O file.
- unsigned cmdSize(bool is64Bit) const {
- if (is64Bit)
- return 7 * sizeof(uint32_t) + 2 * sizeof(uint64_t) + 32;
- else
- return 9 * sizeof(uint32_t) + 32; // addresses only 32 bits
- }
-
- MachOSection(const std::string &seg, const std::string &sect)
- : BinaryObject(), sectname(sect), segname(seg), addr(0), offset(0),
- align(2), reloff(0), nreloc(0), flags(0), reserved1(0), reserved2(0),
- reserved3(0) { }
-
-}; // end struct MachOSection
-
-/// MachOSymTab - This struct contains information about the offsets and
-/// size of symbol table information.
-/// segment.
-struct MachODySymTab {
- uint32_t cmd; // LC_DYSYMTAB
- uint32_t cmdsize; // sizeof(MachODySymTab)
- uint32_t ilocalsym; // index to local symbols
- uint32_t nlocalsym; // number of local symbols
- uint32_t iextdefsym; // index to externally defined symbols
- uint32_t nextdefsym; // number of externally defined symbols
- uint32_t iundefsym; // index to undefined symbols
- uint32_t nundefsym; // number of undefined symbols
- uint32_t tocoff; // file offset to table of contents
- uint32_t ntoc; // number of entries in table of contents
- uint32_t modtaboff; // file offset to module table
- uint32_t nmodtab; // number of module table entries
- uint32_t extrefsymoff; // offset to referenced symbol table
- uint32_t nextrefsyms; // number of referenced symbol table entries
- uint32_t indirectsymoff; // file offset to the indirect symbol table
- uint32_t nindirectsyms; // number of indirect symbol table entries
- uint32_t extreloff; // offset to external relocation entries
- uint32_t nextrel; // number of external relocation entries
- uint32_t locreloff; // offset to local relocation entries
- uint32_t nlocrel; // number of local relocation entries
-
- // Constants for the cmd field
- // see <mach-o/loader.h>
- enum { LC_DYSYMTAB = 0x0B // dynamic link-edit symbol table info
- };
-
- MachODySymTab() : cmd(LC_DYSYMTAB), cmdsize(20 * sizeof(uint32_t)),
- ilocalsym(0), nlocalsym(0), iextdefsym(0), nextdefsym(0),
- iundefsym(0), nundefsym(0), tocoff(0), ntoc(0), modtaboff(0),
- nmodtab(0), extrefsymoff(0), nextrefsyms(0), indirectsymoff(0),
- nindirectsyms(0), extreloff(0), nextrel(0), locreloff(0), nlocrel(0) {}
-
-}; // end struct MachODySymTab
-
-} // end namespace llvm
-
-#endif
-
diff --git a/lib/CodeGen/MachOCodeEmitter.cpp b/lib/CodeGen/MachOCodeEmitter.cpp
deleted file mode 100644
index 1318477..0000000
--- a/lib/CodeGen/MachOCodeEmitter.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-//===-- MachOEmitter.cpp - Target-independent Mach-O Emitter code --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MachO.h"
-#include "MachOWriter.h"
-#include "MachOCodeEmitter.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/CodeGen/MachineConstantPool.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineJumpTableInfo.h"
-#include "llvm/CodeGen/MachineRelocation.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Mangler.h"
-#include "llvm/Support/OutputBuffer.h"
-#include <vector>
-
-//===----------------------------------------------------------------------===//
-// MachOCodeEmitter Implementation
-//===----------------------------------------------------------------------===//
-
-namespace llvm {
-
-MachOCodeEmitter::MachOCodeEmitter(MachOWriter &mow, MachOSection &mos) :
- ObjectCodeEmitter(&mos), MOW(mow), TM(MOW.TM) {
- is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
- isLittleEndian = TM.getTargetData()->isLittleEndian();
- MAI = TM.getMCAsmInfo();
-}
-
-/// startFunction - This callback is invoked when a new machine function is
-/// about to be emitted.
-
-void MachOCodeEmitter::startFunction(MachineFunction &MF) {
- const TargetData *TD = TM.getTargetData();
- const Function *F = MF.getFunction();
-
- // Align the output buffer to the appropriate alignment, power of 2.
- unsigned FnAlign = F->getAlignment();
- unsigned TDAlign = TD->getPrefTypeAlignment(F->getType());
- unsigned Align = Log2_32(std::max(FnAlign, TDAlign));
- assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
-
- // Get the Mach-O Section that this function belongs in.
- MachOSection *MOS = MOW.getTextSection();
-
- // Upgrade the section alignment if required.
- if (MOS->align < Align) MOS->align = Align;
-
- MOS->emitAlignment(Align);
-
- // Create symbol for function entry
- const GlobalValue *FuncV = MF.getFunction();
- MachOSym FnSym(FuncV, MOW.Mang->getMangledName(FuncV), MOS->Index, MAI);
- FnSym.n_value = getCurrentPCOffset();
-
- // add it to the symtab.
- MOW.SymbolTable.push_back(FnSym);
-}
-
-/// finishFunction - This callback is invoked after the function is completely
-/// finished.
-
-bool MachOCodeEmitter::finishFunction(MachineFunction &MF) {
-
- // Get the Mach-O Section that this function belongs in.
- MachOSection *MOS = MOW.getTextSection();
-
- // Emit constant pool to appropriate section(s)
- emitConstantPool(MF.getConstantPool());
-
- // Emit jump tables to appropriate section
- emitJumpTables(MF.getJumpTableInfo());
-
- // If we have emitted any relocations to function-specific objects such as
- // basic blocks, constant pools entries, or jump tables, record their
- // addresses now so that we can rewrite them with the correct addresses
- // later.
- for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
- MachineRelocation &MR = Relocations[i];
- intptr_t Addr;
-
- if (MR.isBasicBlock()) {
- Addr = getMachineBasicBlockAddress(MR.getBasicBlock());
- MR.setConstantVal(MOS->Index);
- MR.setResultPointer((void*)Addr);
- } else if (MR.isJumpTableIndex()) {
- Addr = getJumpTableEntryAddress(MR.getJumpTableIndex());
- MR.setConstantVal(MOW.getJumpTableSection()->Index);
- MR.setResultPointer((void*)Addr);
- } else if (MR.isConstantPoolIndex()) {
- Addr = getConstantPoolEntryAddress(MR.getConstantPoolIndex());
- MR.setConstantVal(CPSections[MR.getConstantPoolIndex()]);
- MR.setResultPointer((void*)Addr);
- } else if (MR.isGlobalValue()) {
- // FIXME: This should be a set or something that uniques
- MOW.PendingGlobals.push_back(MR.getGlobalValue());
- } else {
- llvm_unreachable("Unhandled relocation type");
- }
- MOS->addRelocation(MR);
- }
- Relocations.clear();
-
- // Clear per-function data structures.
- CPLocations.clear();
- CPSections.clear();
- JTLocations.clear();
- MBBLocations.clear();
-
- return false;
-}
-
-/// emitConstantPool - For each constant pool entry, figure out which section
-/// the constant should live in, allocate space for it, and emit it to the
-/// Section data buffer.
-void MachOCodeEmitter::emitConstantPool(MachineConstantPool *MCP) {
- const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();
- if (CP.empty()) return;
-
- // FIXME: handle PIC codegen
- assert(TM.getRelocationModel() != Reloc::PIC_ &&
- "PIC codegen not yet handled for mach-o jump tables!");
-
- // Although there is no strict necessity that I am aware of, we will do what
- // gcc for OS X does and put each constant pool entry in a section of constant
- // objects of a certain size. That means that float constants go in the
- // literal4 section, and double objects go in literal8, etc.
- //
- // FIXME: revisit this decision if we ever do the "stick everything into one
- // "giant object for PIC" optimization.
- for (unsigned i = 0, e = CP.size(); i != e; ++i) {
- const Type *Ty = CP[i].getType();
- unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
-
- MachOSection *Sec = MOW.getConstSection(CP[i].Val.ConstVal);
- OutputBuffer SecDataOut(Sec->getData(), is64Bit, isLittleEndian);
-
- CPLocations.push_back(Sec->size());
- CPSections.push_back(Sec->Index);
-
- // Allocate space in the section for the global.
- // FIXME: need alignment?
- // FIXME: share between here and AddSymbolToSection?
- for (unsigned j = 0; j < Size; ++j)
- SecDataOut.outbyte(0);
-
- MachOWriter::InitMem(CP[i].Val.ConstVal, CPLocations[i],
- TM.getTargetData(), Sec);
- }
-}
-
-/// emitJumpTables - Emit all the jump tables for a given jump table info
-/// record to the appropriate section.
-void MachOCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) {
- const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
- if (JT.empty()) return;
-
- // FIXME: handle PIC codegen
- assert(TM.getRelocationModel() != Reloc::PIC_ &&
- "PIC codegen not yet handled for mach-o jump tables!");
-
- MachOSection *Sec = MOW.getJumpTableSection();
- unsigned TextSecIndex = MOW.getTextSection()->Index;
- OutputBuffer SecDataOut(Sec->getData(), is64Bit, isLittleEndian);
-
- for (unsigned i = 0, e = JT.size(); i != e; ++i) {
- // For each jump table, record its offset from the start of the section,
- // reserve space for the relocations to the MBBs, and add the relocations.
- const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs;
- JTLocations.push_back(Sec->size());
- for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) {
- MachineRelocation MR(MOW.GetJTRelocation(Sec->size(), MBBs[mi]));
- MR.setResultPointer((void *)JTLocations[i]);
- MR.setConstantVal(TextSecIndex);
- Sec->addRelocation(MR);
- SecDataOut.outaddr(0);
- }
- }
-}
-
-} // end namespace llvm
-
diff --git a/lib/CodeGen/MachOCodeEmitter.h b/lib/CodeGen/MachOCodeEmitter.h
deleted file mode 100644
index 4752446..0000000
--- a/lib/CodeGen/MachOCodeEmitter.h
+++ /dev/null
@@ -1,69 +0,0 @@
-//===-- MachOEmitter.h - Target-independent Mach-O Emitter class ----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef MACHOCODEEMITTER_H
-#define MACHOCODEEMITTER_H
-
-#include "llvm/CodeGen/ObjectCodeEmitter.h"
-#include <map>
-
-namespace llvm {
-
-class MachOWriter;
-
-/// MachOCodeEmitter - This class is used by the MachOWriter to emit the code
-/// for functions to the Mach-O file.
-
-class MachOCodeEmitter : public ObjectCodeEmitter {
- MachOWriter &MOW;
-
- /// Target machine description.
- TargetMachine &TM;
-
- /// is64Bit/isLittleEndian - This information is inferred from the target
- /// machine directly, indicating what header values and flags to set.
- bool is64Bit, isLittleEndian;
-
- const MCAsmInfo *MAI;
-
- /// Relocations - These are the relocations that the function needs, as
- /// emitted.
- std::vector<MachineRelocation> Relocations;
-
- std::map<uint64_t, uintptr_t> Labels;
-
-public:
- MachOCodeEmitter(MachOWriter &mow, MachOSection &mos);
-
- virtual void startFunction(MachineFunction &MF);
- virtual bool finishFunction(MachineFunction &MF);
-
- virtual void addRelocation(const MachineRelocation &MR) {
- Relocations.push_back(MR);
- }
-
- void emitConstantPool(MachineConstantPool *MCP);
- void emitJumpTables(MachineJumpTableInfo *MJTI);
-
- virtual void emitLabel(uint64_t LabelID) {
- Labels[LabelID] = getCurrentPCOffset();
- }
-
- virtual uintptr_t getLabelAddress(uint64_t Label) const {
- return Labels.find(Label)->second;
- }
-
- virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
-
-}; // end class MachOCodeEmitter
-
-} // end namespace llvm
-
-#endif
-
diff --git a/lib/CodeGen/MachOWriter.cpp b/lib/CodeGen/MachOWriter.cpp
index 337eab1..e8bbe21 100644
--- a/lib/CodeGen/MachOWriter.cpp
+++ b/lib/CodeGen/MachOWriter.cpp
@@ -22,33 +22,31 @@
//
//===----------------------------------------------------------------------===//
-#include "MachO.h"
#include "MachOWriter.h"
-#include "MachOCodeEmitter.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.h"
-#include "llvm/PassManager.h"
+#include "llvm/Function.h"
+#include "llvm/CodeGen/FileWriters.h"
+#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetMachOWriterInfo.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/Mangler.h"
-#include "llvm/Support/OutputBuffer.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/Mangler.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetLowering.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+using namespace llvm;
-namespace llvm {
-
-/// AddMachOWriter - Concrete function to add the Mach-O writer to the function
-/// pass manager.
-ObjectCodeEmitter *AddMachOWriter(PassManagerBase &PM,
- raw_ostream &O,
- TargetMachine &TM) {
- MachOWriter *MOW = new MachOWriter(O, TM);
- PM.add(MOW);
- return MOW->getObjectCodeEmitter();
+namespace llvm {
+MachineFunctionPass *createMachOWriter(formatted_raw_ostream &O,
+ TargetMachine &TM,
+ const MCAsmInfo *T,
+ MCCodeEmitter *MCE) {
+ return new MachOWriter(O, TM, T, MCE);
+}
}
//===----------------------------------------------------------------------===//
@@ -57,722 +55,71 @@ ObjectCodeEmitter *AddMachOWriter(PassManagerBase &PM,
char MachOWriter::ID = 0;
-MachOWriter::MachOWriter(raw_ostream &o, TargetMachine &tm)
- : MachineFunctionPass(&ID), O(o), TM(tm) {
- is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
- isLittleEndian = TM.getTargetData()->isLittleEndian();
-
- MAI = TM.getMCAsmInfo();
-
- // Create the machine code emitter object for this target.
- MachOCE = new MachOCodeEmitter(*this, *getTextSection(true));
+MachOWriter::MachOWriter(formatted_raw_ostream &o, TargetMachine &tm,
+ const MCAsmInfo *T, MCCodeEmitter *MCE)
+ : MachineFunctionPass(&ID), O(o), TM(tm), MAI(T), MCCE(MCE),
+ OutContext(*new MCContext()),
+ OutStreamer(*createMachOStreamer(OutContext, O, MCCE)) {
}
MachOWriter::~MachOWriter() {
- delete MachOCE;
+ delete &OutStreamer;
+ delete &OutContext;
+ delete MCCE;
}
bool MachOWriter::doInitialization(Module &M) {
- // Set the magic value, now that we know the pointer size and endianness
- Header.setMagic(isLittleEndian, is64Bit);
-
- // Set the file type
- // FIXME: this only works for object files, we do not support the creation
- // of dynamic libraries or executables at this time.
- Header.filetype = MachOHeader::MH_OBJECT;
+ // Initialize TargetLoweringObjectFile.
+ TM.getTargetLowering()->getObjFileLowering().Initialize(OutContext, TM);
- Mang = new Mangler(M);
- return false;
-}
-
-bool MachOWriter::runOnMachineFunction(MachineFunction &MF) {
return false;
}
/// doFinalization - Now that the module has been completely processed, emit
/// the Mach-O file to 'O'.
bool MachOWriter::doFinalization(Module &M) {
- // FIXME: we don't handle debug info yet, we should probably do that.
- // Okay, the.text section has been completed, build the .data, .bss, and
- // "common" sections next.
-
- for (Module::global_iterator I = M.global_begin(), E = M.global_end();
- I != E; ++I)
- EmitGlobal(I);
-
- // Emit the header and load commands.
- EmitHeaderAndLoadCommands();
-
- // Emit the various sections and their relocation info.
- EmitSections();
- EmitRelocations();
-
- // Write the symbol table and the string table to the end of the file.
- O.write((char*)&SymT[0], SymT.size());
- O.write((char*)&StrT[0], StrT.size());
-
- // We are done with the abstract symbols.
- SectionList.clear();
- SymbolTable.clear();
- DynamicSymbolTable.clear();
-
- // Release the name mangler object.
- delete Mang; Mang = 0;
+ OutStreamer.Finish();
return false;
}
-// getConstSection - Get constant section for Constant 'C'
-MachOSection *MachOWriter::getConstSection(Constant *C) {
- const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
- if (CVA && CVA->isCString())
- return getSection("__TEXT", "__cstring",
- MachOSection::S_CSTRING_LITERALS);
-
- const Type *Ty = C->getType();
- if (Ty->isPrimitiveType() || Ty->isInteger()) {
- unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
- switch(Size) {
- default: break; // Fall through to __TEXT,__const
- case 4:
- return getSection("__TEXT", "__literal4",
- MachOSection::S_4BYTE_LITERALS);
- case 8:
- return getSection("__TEXT", "__literal8",
- MachOSection::S_8BYTE_LITERALS);
- case 16:
- return getSection("__TEXT", "__literal16",
- MachOSection::S_16BYTE_LITERALS);
- }
- }
- return getSection("__TEXT", "__const");
-}
-
-// getJumpTableSection - Select the Jump Table section
-MachOSection *MachOWriter::getJumpTableSection() {
- if (TM.getRelocationModel() == Reloc::PIC_)
- return getTextSection(false);
- else
- return getSection("__TEXT", "__const");
-}
-
-// getSection - Return the section with the specified name, creating a new
-// section if one does not already exist.
-MachOSection *MachOWriter::getSection(const std::string &seg,
- const std::string &sect,
- unsigned Flags /* = 0 */ ) {
- MachOSection *MOS = SectionLookup[seg+sect];
- if (MOS) return MOS;
-
- MOS = new MachOSection(seg, sect);
- SectionList.push_back(MOS);
- MOS->Index = SectionList.size();
- MOS->flags = MachOSection::S_REGULAR | Flags;
- SectionLookup[seg+sect] = MOS;
- return MOS;
-}
-
-// getTextSection - Return text section with different flags for code/data
-MachOSection *MachOWriter::getTextSection(bool isCode /* = true */ ) {
- if (isCode)
- return getSection("__TEXT", "__text",
- MachOSection::S_ATTR_PURE_INSTRUCTIONS |
- MachOSection::S_ATTR_SOME_INSTRUCTIONS);
- else
- return getSection("__TEXT", "__text");
-}
-
-MachOSection *MachOWriter::getBSSSection() {
- return getSection("__DATA", "__bss", MachOSection::S_ZEROFILL);
-}
-
-// GetJTRelocation - Get a relocation a new BB relocation based
-// on target information.
-MachineRelocation MachOWriter::GetJTRelocation(unsigned Offset,
- MachineBasicBlock *MBB) const {
- return TM.getMachOWriterInfo()->GetJTRelocation(Offset, MBB);
-}
-
-// GetTargetRelocation - Returns the number of relocations.
-unsigned MachOWriter::GetTargetRelocation(MachineRelocation &MR,
- unsigned FromIdx, unsigned ToAddr,
- unsigned ToIndex, OutputBuffer &RelocOut,
- OutputBuffer &SecOut, bool Scattered,
- bool Extern) {
- return TM.getMachOWriterInfo()->GetTargetRelocation(MR, FromIdx, ToAddr,
- ToIndex, RelocOut,
- SecOut, Scattered,
- Extern);
-}
-
-void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) {
- const Type *Ty = GV->getType()->getElementType();
- unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
- unsigned Align = TM.getTargetData()->getPreferredAlignment(GV);
-
- // Reserve space in the .bss section for this symbol while maintaining the
- // desired section alignment, which must be at least as much as required by
- // this symbol.
- OutputBuffer SecDataOut(Sec->getData(), is64Bit, isLittleEndian);
-
- if (Align) {
- Align = Log2_32(Align);
- Sec->align = std::max(unsigned(Sec->align), Align);
-
- Sec->emitAlignment(Sec->align);
- }
- // Globals without external linkage apparently do not go in the symbol table.
- if (!GV->hasLocalLinkage()) {
- MachOSym Sym(GV, Mang->getMangledName(GV), Sec->Index, MAI);
- Sym.n_value = Sec->size();
- SymbolTable.push_back(Sym);
- }
-
- // Record the offset of the symbol, and then allocate space for it.
- // FIXME: remove when we have unified size + output buffer
-
- // Now that we know what section the GlovalVariable is going to be emitted
- // into, update our mappings.
- // FIXME: We may also need to update this when outputting non-GlobalVariable
- // GlobalValues such as functions.
-
- GVSection[GV] = Sec;
- GVOffset[GV] = Sec->size();
-
- // Allocate space in the section for the global.
- for (unsigned i = 0; i < Size; ++i)
- SecDataOut.outbyte(0);
-}
-
-void MachOWriter::EmitGlobal(GlobalVariable *GV) {
- const Type *Ty = GV->getType()->getElementType();
- unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
- bool NoInit = !GV->hasInitializer();
-
- // If this global has a zero initializer, it is part of the .bss or common
- // section.
- if (NoInit || GV->getInitializer()->isNullValue()) {
- // If this global is part of the common block, add it now. Variables are
- // part of the common block if they are zero initialized and allowed to be
- // merged with other symbols.
- if (NoInit || GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
- GV->hasCommonLinkage()) {
- MachOSym ExtOrCommonSym(GV, Mang->getMangledName(GV),
- MachOSym::NO_SECT, MAI);
- // For undefined (N_UNDF) external (N_EXT) types, n_value is the size in
- // bytes of the symbol.
- ExtOrCommonSym.n_value = Size;
- SymbolTable.push_back(ExtOrCommonSym);
- // Remember that we've seen this symbol
- GVOffset[GV] = Size;
- return;
- }
- // Otherwise, this symbol is part of the .bss section.
- MachOSection *BSS = getBSSSection();
- AddSymbolToSection(BSS, GV);
- return;
- }
-
- // Scalar read-only data goes in a literal section if the scalar is 4, 8, or
- // 16 bytes, or a cstring. Other read only data goes into a regular const
- // section. Read-write data goes in the data section.
- MachOSection *Sec = GV->isConstant() ? getConstSection(GV->getInitializer()) :
- getDataSection();
- AddSymbolToSection(Sec, GV);
- InitMem(GV->getInitializer(), GVOffset[GV], TM.getTargetData(), Sec);
-}
-
-
-
-void MachOWriter::EmitHeaderAndLoadCommands() {
- // Step #0: Fill in the segment load command size, since we need it to figure
- // out the rest of the header fields
-
- MachOSegment SEG("", is64Bit);
- SEG.nsects = SectionList.size();
- SEG.cmdsize = SEG.cmdSize(is64Bit) +
- SEG.nsects * SectionList[0]->cmdSize(is64Bit);
-
- // Step #1: calculate the number of load commands. We always have at least
- // one, for the LC_SEGMENT load command, plus two for the normal
- // and dynamic symbol tables, if there are any symbols.
- Header.ncmds = SymbolTable.empty() ? 1 : 3;
-
- // Step #2: calculate the size of the load commands
- Header.sizeofcmds = SEG.cmdsize;
- if (!SymbolTable.empty())
- Header.sizeofcmds += SymTab.cmdsize + DySymTab.cmdsize;
-
- // Step #3: write the header to the file
- // Local alias to shortenify coming code.
- std::vector<unsigned char> &FH = Header.HeaderData;
- OutputBuffer FHOut(FH, is64Bit, isLittleEndian);
-
- FHOut.outword(Header.magic);
- FHOut.outword(TM.getMachOWriterInfo()->getCPUType());
- FHOut.outword(TM.getMachOWriterInfo()->getCPUSubType());
- FHOut.outword(Header.filetype);
- FHOut.outword(Header.ncmds);
- FHOut.outword(Header.sizeofcmds);
- FHOut.outword(Header.flags);
- if (is64Bit)
- FHOut.outword(Header.reserved);
-
- // Step #4: Finish filling in the segment load command and write it out
- for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
- E = SectionList.end(); I != E; ++I)
- SEG.filesize += (*I)->size();
-
- SEG.vmsize = SEG.filesize;
- SEG.fileoff = Header.cmdSize(is64Bit) + Header.sizeofcmds;
-
- FHOut.outword(SEG.cmd);
- FHOut.outword(SEG.cmdsize);
- FHOut.outstring(SEG.segname, 16);
- FHOut.outaddr(SEG.vmaddr);
- FHOut.outaddr(SEG.vmsize);
- FHOut.outaddr(SEG.fileoff);
- FHOut.outaddr(SEG.filesize);
- FHOut.outword(SEG.maxprot);
- FHOut.outword(SEG.initprot);
- FHOut.outword(SEG.nsects);
- FHOut.outword(SEG.flags);
-
- // Step #5: Finish filling in the fields of the MachOSections
- uint64_t currentAddr = 0;
- for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
- E = SectionList.end(); I != E; ++I) {
- MachOSection *MOS = *I;
- MOS->addr = currentAddr;
- MOS->offset = currentAddr + SEG.fileoff;
- // FIXME: do we need to do something with alignment here?
- currentAddr += MOS->size();
- }
-
- // Step #6: Emit the symbol table to temporary buffers, so that we know the
- // size of the string table when we write the next load command. This also
- // sorts and assigns indices to each of the symbols, which is necessary for
- // emitting relocations to externally-defined objects.
- BufferSymbolAndStringTable();
-
- // Step #7: Calculate the number of relocations for each section and write out
- // the section commands for each section
- currentAddr += SEG.fileoff;
- for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
- E = SectionList.end(); I != E; ++I) {
- MachOSection *MOS = *I;
-
- // Convert the relocations to target-specific relocations, and fill in the
- // relocation offset for this section.
- CalculateRelocations(*MOS);
- MOS->reloff = MOS->nreloc ? currentAddr : 0;
- currentAddr += MOS->nreloc * 8;
-
- // write the finalized section command to the output buffer
- FHOut.outstring(MOS->sectname, 16);
- FHOut.outstring(MOS->segname, 16);
- FHOut.outaddr(MOS->addr);
- FHOut.outaddr(MOS->size());
- FHOut.outword(MOS->offset);
- FHOut.outword(MOS->align);
- FHOut.outword(MOS->reloff);
- FHOut.outword(MOS->nreloc);
- FHOut.outword(MOS->flags);
- FHOut.outword(MOS->reserved1);
- FHOut.outword(MOS->reserved2);
- if (is64Bit)
- FHOut.outword(MOS->reserved3);
- }
-
- // Step #8: Emit LC_SYMTAB/LC_DYSYMTAB load commands
- SymTab.symoff = currentAddr;
- SymTab.nsyms = SymbolTable.size();
- SymTab.stroff = SymTab.symoff + SymT.size();
- SymTab.strsize = StrT.size();
- FHOut.outword(SymTab.cmd);
- FHOut.outword(SymTab.cmdsize);
- FHOut.outword(SymTab.symoff);
- FHOut.outword(SymTab.nsyms);
- FHOut.outword(SymTab.stroff);
- FHOut.outword(SymTab.strsize);
-
- // FIXME: set DySymTab fields appropriately
- // We should probably just update these in BufferSymbolAndStringTable since
- // thats where we're partitioning up the different kinds of symbols.
- FHOut.outword(DySymTab.cmd);
- FHOut.outword(DySymTab.cmdsize);
- FHOut.outword(DySymTab.ilocalsym);
- FHOut.outword(DySymTab.nlocalsym);
- FHOut.outword(DySymTab.iextdefsym);
- FHOut.outword(DySymTab.nextdefsym);
- FHOut.outword(DySymTab.iundefsym);
- FHOut.outword(DySymTab.nundefsym);
- FHOut.outword(DySymTab.tocoff);
- FHOut.outword(DySymTab.ntoc);
- FHOut.outword(DySymTab.modtaboff);
- FHOut.outword(DySymTab.nmodtab);
- FHOut.outword(DySymTab.extrefsymoff);
- FHOut.outword(DySymTab.nextrefsyms);
- FHOut.outword(DySymTab.indirectsymoff);
- FHOut.outword(DySymTab.nindirectsyms);
- FHOut.outword(DySymTab.extreloff);
- FHOut.outword(DySymTab.nextrel);
- FHOut.outword(DySymTab.locreloff);
- FHOut.outword(DySymTab.nlocrel);
-
- O.write((char*)&FH[0], FH.size());
-}
-
-/// EmitSections - Now that we have constructed the file header and load
-/// commands, emit the data for each section to the file.
-void MachOWriter::EmitSections() {
- for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
- E = SectionList.end(); I != E; ++I)
- // Emit the contents of each section
- if ((*I)->size())
- O.write((char*)&(*I)->getData()[0], (*I)->size());
-}
-
-/// EmitRelocations - emit relocation data from buffer.
-void MachOWriter::EmitRelocations() {
- for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
- E = SectionList.end(); I != E; ++I)
- // Emit the relocation entry data for each section.
- if ((*I)->RelocBuffer.size())
- O.write((char*)&(*I)->RelocBuffer[0], (*I)->RelocBuffer.size());
-}
-
-/// BufferSymbolAndStringTable - Sort the symbols we encountered and assign them
-/// each a string table index so that they appear in the correct order in the
-/// output file.
-void MachOWriter::BufferSymbolAndStringTable() {
- // The order of the symbol table is:
- // 1. local symbols
- // 2. defined external symbols (sorted by name)
- // 3. undefined external symbols (sorted by name)
-
- // Before sorting the symbols, check the PendingGlobals for any undefined
- // globals that need to be put in the symbol table.
- for (std::vector<GlobalValue*>::iterator I = PendingGlobals.begin(),
- E = PendingGlobals.end(); I != E; ++I) {
- if (GVOffset[*I] == 0 && GVSection[*I] == 0) {
- MachOSym UndfSym(*I, Mang->getMangledName(*I), MachOSym::NO_SECT, MAI);
- SymbolTable.push_back(UndfSym);
- GVOffset[*I] = -1;
- }
- }
-
- // Sort the symbols by name, so that when we partition the symbols by scope
- // of definition, we won't have to sort by name within each partition.
- std::sort(SymbolTable.begin(), SymbolTable.end(), MachOSym::SymCmp());
-
- // Parition the symbol table entries so that all local symbols come before
- // all symbols with external linkage. { 1 | 2 3 }
- std::partition(SymbolTable.begin(), SymbolTable.end(),
- MachOSym::PartitionByLocal);
-
- // Advance iterator to beginning of external symbols and partition so that
- // all external symbols defined in this module come before all external
- // symbols defined elsewhere. { 1 | 2 | 3 }
- for (std::vector<MachOSym>::iterator I = SymbolTable.begin(),
- E = SymbolTable.end(); I != E; ++I) {
- if (!MachOSym::PartitionByLocal(*I)) {
- std::partition(I, E, MachOSym::PartitionByDefined);
- break;
- }
- }
-
- // Calculate the starting index for each of the local, extern defined, and
- // undefined symbols, as well as the number of each to put in the LC_DYSYMTAB
- // load command.
- for (std::vector<MachOSym>::iterator I = SymbolTable.begin(),
- E = SymbolTable.end(); I != E; ++I) {
- if (MachOSym::PartitionByLocal(*I)) {
- ++DySymTab.nlocalsym;
- ++DySymTab.iextdefsym;
- ++DySymTab.iundefsym;
- } else if (MachOSym::PartitionByDefined(*I)) {
- ++DySymTab.nextdefsym;
- ++DySymTab.iundefsym;
- } else {
- ++DySymTab.nundefsym;
- }
- }
-
- // Write out a leading zero byte when emitting string table, for n_strx == 0
- // which means an empty string.
- OutputBuffer StrTOut(StrT, is64Bit, isLittleEndian);
- StrTOut.outbyte(0);
-
- // The order of the string table is:
- // 1. strings for external symbols
- // 2. strings for local symbols
- // Since this is the opposite order from the symbol table, which we have just
- // sorted, we can walk the symbol table backwards to output the string table.
- for (std::vector<MachOSym>::reverse_iterator I = SymbolTable.rbegin(),
- E = SymbolTable.rend(); I != E; ++I) {
- if (I->GVName == "") {
- I->n_strx = 0;
- } else {
- I->n_strx = StrT.size();
- StrTOut.outstring(I->GVName, I->GVName.length()+1);
- }
- }
-
- OutputBuffer SymTOut(SymT, is64Bit, isLittleEndian);
-
- unsigned index = 0;
- for (std::vector<MachOSym>::iterator I = SymbolTable.begin(),
- E = SymbolTable.end(); I != E; ++I, ++index) {
- // Add the section base address to the section offset in the n_value field
- // to calculate the full address.
- // FIXME: handle symbols where the n_value field is not the address
- GlobalValue *GV = const_cast<GlobalValue*>(I->GV);
- if (GV && GVSection[GV])
- I->n_value += GVSection[GV]->addr;
- if (GV && (GVOffset[GV] == -1))
- GVOffset[GV] = index;
-
- // Emit nlist to buffer
- SymTOut.outword(I->n_strx);
- SymTOut.outbyte(I->n_type);
- SymTOut.outbyte(I->n_sect);
- SymTOut.outhalf(I->n_desc);
- SymTOut.outaddr(I->n_value);
- }
-}
-
-/// CalculateRelocations - For each MachineRelocation in the current section,
-/// calculate the index of the section containing the object to be relocated,
-/// and the offset into that section. From this information, create the
-/// appropriate target-specific MachORelocation type and add buffer it to be
-/// written out after we are finished writing out sections.
-void MachOWriter::CalculateRelocations(MachOSection &MOS) {
- std::vector<MachineRelocation> Relocations = MOS.getRelocations();
- for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
- MachineRelocation &MR = Relocations[i];
- unsigned TargetSection = MR.getConstantVal();
- unsigned TargetAddr = 0;
- unsigned TargetIndex = 0;
-
- // This is a scattered relocation entry if it points to a global value with
- // a non-zero offset.
- bool Scattered = false;
- bool Extern = false;
-
- // Since we may not have seen the GlobalValue we were interested in yet at
- // the time we emitted the relocation for it, fix it up now so that it
- // points to the offset into the correct section.
- if (MR.isGlobalValue()) {
- GlobalValue *GV = MR.getGlobalValue();
- MachOSection *MOSPtr = GVSection[GV];
- intptr_t Offset = GVOffset[GV];
-
- // If we have never seen the global before, it must be to a symbol
- // defined in another module (N_UNDF).
- if (!MOSPtr) {
- // FIXME: need to append stub suffix
- Extern = true;
- TargetAddr = 0;
- TargetIndex = GVOffset[GV];
- } else {
- Scattered = TargetSection != 0;
- TargetSection = MOSPtr->Index;
- }
- MR.setResultPointer((void*)Offset);
- }
-
- // If the symbol is locally defined, pass in the address of the section and
- // the section index to the code which will generate the target relocation.
- if (!Extern) {
- MachOSection &To = *SectionList[TargetSection - 1];
- TargetAddr = To.addr;
- TargetIndex = To.Index;
- }
-
- OutputBuffer RelocOut(MOS.RelocBuffer, is64Bit, isLittleEndian);
- OutputBuffer SecOut(MOS.getData(), is64Bit, isLittleEndian);
-
- MOS.nreloc += GetTargetRelocation(MR, MOS.Index, TargetAddr, TargetIndex,
- RelocOut, SecOut, Scattered, Extern);
- }
-}
-
-// InitMem - Write the value of a Constant to the specified memory location,
-// converting it into bytes and relocations.
-void MachOWriter::InitMem(const Constant *C, uintptr_t Offset,
- const TargetData *TD, MachOSection* mos) {
- typedef std::pair<const Constant*, intptr_t> CPair;
- std::vector<CPair> WorkList;
- uint8_t *Addr = &mos->getData()[0];
-
- WorkList.push_back(CPair(C,(intptr_t)Addr + Offset));
-
- intptr_t ScatteredOffset = 0;
-
- while (!WorkList.empty()) {
- const Constant *PC = WorkList.back().first;
- intptr_t PA = WorkList.back().second;
- WorkList.pop_back();
-
- if (isa<UndefValue>(PC)) {
- continue;
- } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(PC)) {
- unsigned ElementSize =
- TD->getTypeAllocSize(CP->getType()->getElementType());
- for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
- WorkList.push_back(CPair(CP->getOperand(i), PA+i*ElementSize));
- } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(PC)) {
- //
- // FIXME: Handle ConstantExpression. See EE::getConstantValue()
- //
- switch (CE->getOpcode()) {
- case Instruction::GetElementPtr: {
- SmallVector<Value*, 8> Indices(CE->op_begin()+1, CE->op_end());
- ScatteredOffset = TD->getIndexedOffset(CE->getOperand(0)->getType(),
- &Indices[0], Indices.size());
- WorkList.push_back(CPair(CE->getOperand(0), PA));
- break;
- }
- case Instruction::Add:
- default:
- dbgs() << "ConstantExpr not handled as global var init: " << *CE <<"\n";
- llvm_unreachable(0);
- }
- } else if (PC->getType()->isSingleValueType()) {
- unsigned char *ptr = (unsigned char *)PA;
- switch (PC->getType()->getTypeID()) {
- case Type::IntegerTyID: {
- unsigned NumBits = cast<IntegerType>(PC->getType())->getBitWidth();
- uint64_t val = cast<ConstantInt>(PC)->getZExtValue();
- if (NumBits <= 8)
- ptr[0] = val;
- else if (NumBits <= 16) {
- if (TD->isBigEndian())
- val = ByteSwap_16(val);
- ptr[0] = val;
- ptr[1] = val >> 8;
- } else if (NumBits <= 32) {
- if (TD->isBigEndian())
- val = ByteSwap_32(val);
- ptr[0] = val;
- ptr[1] = val >> 8;
- ptr[2] = val >> 16;
- ptr[3] = val >> 24;
- } else if (NumBits <= 64) {
- if (TD->isBigEndian())
- val = ByteSwap_64(val);
- ptr[0] = val;
- ptr[1] = val >> 8;
- ptr[2] = val >> 16;
- ptr[3] = val >> 24;
- ptr[4] = val >> 32;
- ptr[5] = val >> 40;
- ptr[6] = val >> 48;
- ptr[7] = val >> 56;
- } else {
- llvm_unreachable("Not implemented: bit widths > 64");
+bool MachOWriter::runOnMachineFunction(MachineFunction &MF) {
+ const Function *F = MF.getFunction();
+ TargetLoweringObjectFile &TLOF = TM.getTargetLowering()->getObjFileLowering();
+ const MCSection *S = TLOF.SectionForGlobal(F, Mang, TM);
+ OutStreamer.SwitchSection(S);
+
+ for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
+ I != E; ++I) {
+ // Print a label for the basic block.
+ for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
+ II != IE; ++II) {
+ const MachineInstr *MI = II;
+ MCInst OutMI;
+ OutMI.setOpcode(MI->getOpcode());
+
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = MI->getOperand(i);
+ MCOperand MCOp;
+
+ switch (MO.getType()) {
+ default:
+ MI->dump();
+ llvm_unreachable("unknown operand type");
+ case MachineOperand::MO_Register:
+ // Ignore all implicit register operands.
+ if (MO.isImplicit()) continue;
+ MCOp = MCOperand::CreateReg(MO.getReg());
+ break;
+ case MachineOperand::MO_Immediate:
+ MCOp = MCOperand::CreateImm(MO.getImm());
+ break;
}
- break;
- }
- case Type::FloatTyID: {
- uint32_t val = cast<ConstantFP>(PC)->getValueAPF().bitcastToAPInt().
- getZExtValue();
- if (TD->isBigEndian())
- val = ByteSwap_32(val);
- ptr[0] = val;
- ptr[1] = val >> 8;
- ptr[2] = val >> 16;
- ptr[3] = val >> 24;
- break;
- }
- case Type::DoubleTyID: {
- uint64_t val = cast<ConstantFP>(PC)->getValueAPF().bitcastToAPInt().
- getZExtValue();
- if (TD->isBigEndian())
- val = ByteSwap_64(val);
- ptr[0] = val;
- ptr[1] = val >> 8;
- ptr[2] = val >> 16;
- ptr[3] = val >> 24;
- ptr[4] = val >> 32;
- ptr[5] = val >> 40;
- ptr[6] = val >> 48;
- ptr[7] = val >> 56;
- break;
- }
- case Type::PointerTyID:
- if (isa<ConstantPointerNull>(PC))
- memset(ptr, 0, TD->getPointerSize());
- else if (const GlobalValue* GV = dyn_cast<GlobalValue>(PC)) {
- // FIXME: what about function stubs?
- mos->addRelocation(MachineRelocation::getGV(PA-(intptr_t)Addr,
- MachineRelocation::VANILLA,
- const_cast<GlobalValue*>(GV),
- ScatteredOffset));
- ScatteredOffset = 0;
- } else
- llvm_unreachable("Unknown constant pointer type!");
- break;
- default:
- std::string msg;
- raw_string_ostream Msg(msg);
- Msg << "ERROR: Constant unimp for type: " << *PC->getType();
- llvm_report_error(Msg.str());
+ OutMI.addOperand(MCOp);
}
- } else if (isa<ConstantAggregateZero>(PC)) {
- memset((void*)PA, 0, (size_t)TD->getTypeAllocSize(PC->getType()));
- } else if (const ConstantArray *CPA = dyn_cast<ConstantArray>(PC)) {
- unsigned ElementSize =
- TD->getTypeAllocSize(CPA->getType()->getElementType());
- for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i)
- WorkList.push_back(CPair(CPA->getOperand(i), PA+i*ElementSize));
- } else if (const ConstantStruct *CPS = dyn_cast<ConstantStruct>(PC)) {
- const StructLayout *SL =
- TD->getStructLayout(cast<StructType>(CPS->getType()));
- for (unsigned i = 0, e = CPS->getNumOperands(); i != e; ++i)
- WorkList.push_back(CPair(CPS->getOperand(i),
- PA+SL->getElementOffset(i)));
- } else {
- dbgs() << "Bad Type: " << *PC->getType() << "\n";
- llvm_unreachable("Unknown constant type to initialize memory with!");
+
+ OutStreamer.EmitInstruction(OutMI);
}
}
-}
-
-//===----------------------------------------------------------------------===//
-// MachOSym Implementation
-//===----------------------------------------------------------------------===//
-MachOSym::MachOSym(const GlobalValue *gv, std::string name, uint8_t sect,
- const MCAsmInfo *MAI) :
- GV(gv), n_strx(0), n_type(sect == NO_SECT ? N_UNDF : N_SECT), n_sect(sect),
- n_desc(0), n_value(0) {
-
- // FIXME: This is completely broken, it should use the mangler interface.
- switch (GV->getLinkage()) {
- default:
- llvm_unreachable("Unexpected linkage type!");
- break;
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::CommonLinkage:
- assert(!isa<Function>(gv) && "Unexpected linkage type for Function!");
- case GlobalValue::ExternalLinkage:
- GVName = MAI->getGlobalPrefix() + name;
- n_type |= GV->hasHiddenVisibility() ? N_PEXT : N_EXT;
- break;
- case GlobalValue::PrivateLinkage:
- GVName = MAI->getPrivateGlobalPrefix() + name;
- break;
- case GlobalValue::LinkerPrivateLinkage:
- GVName = MAI->getLinkerPrivateGlobalPrefix() + name;
- break;
- case GlobalValue::InternalLinkage:
- GVName = MAI->getGlobalPrefix() + name;
- break;
- }
+ return false;
}
-
-} // end namespace llvm
diff --git a/lib/CodeGen/MachOWriter.h b/lib/CodeGen/MachOWriter.h
index 9273f38..2e7e67d 100644
--- a/lib/CodeGen/MachOWriter.h
+++ b/lib/CodeGen/MachOWriter.h
@@ -15,191 +15,73 @@
#define MACHOWRITER_H
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include <vector>
-#include <map>
+#include "llvm/Target/TargetMachine.h"
namespace llvm {
- class Constant;
class GlobalVariable;
class Mangler;
- class MachineBasicBlock;
- class MachineRelocation;
- class MachOCodeEmitter;
- struct MachODySymTab;
- struct MachOHeader;
- struct MachOSection;
- struct MachOSym;
- class TargetData;
- class TargetMachine;
- class MCAsmInfo;
- class ObjectCodeEmitter;
- class OutputBuffer;
- class raw_ostream;
-
+ class MCCodeEmitter;
+ class MCContext;
+ class MCStreamer;
+
/// MachOWriter - This class implements the common target-independent code for
/// writing Mach-O files. Targets should derive a class from this to
/// parameterize the output format.
///
class MachOWriter : public MachineFunctionPass {
- friend class MachOCodeEmitter;
- public:
static char ID;
- ObjectCodeEmitter *getObjectCodeEmitter() {
- return reinterpret_cast<ObjectCodeEmitter*>(MachOCE);
- }
-
- MachOWriter(raw_ostream &O, TargetMachine &TM);
- virtual ~MachOWriter();
-
- virtual const char *getPassName() const {
- return "Mach-O Writer";
- }
-
protected:
/// Output stream to send the resultant object file to.
///
- raw_ostream &O;
+ formatted_raw_ostream &O;
/// Target machine description.
///
TargetMachine &TM;
- /// Mang - The object used to perform name mangling for this module.
+ /// Target Asm Printer information.
///
- Mangler *Mang;
-
- /// MachOCE - The MachineCodeEmitter object that we are exposing to emit
- /// machine code for functions to the .o file.
- MachOCodeEmitter *MachOCE;
-
- /// is64Bit/isLittleEndian - This information is inferred from the target
- /// machine directly, indicating what header values and flags to set.
- bool is64Bit, isLittleEndian;
-
- // Target Asm Info
const MCAsmInfo *MAI;
-
- /// Header - An instance of MachOHeader that we will update while we build
- /// the file, and then emit during finalization.
- MachOHeader Header;
-
+
+ /// MCCE - The MCCodeEmitter object that we are exposing to emit machine
+ /// code for functions to the .o file.
+ MCCodeEmitter *MCCE;
+
+ /// OutContext - This is the context for the output file that we are
+ /// streaming. This owns all of the global MC-related objects for the
+ /// generated translation unit.
+ MCContext &OutContext;
+
+ /// OutStreamer - This is the MCStreamer object for the file we are
+ /// generating. This contains the transient state for the current
+ /// translation unit that we are generating (such as the current section
+ /// etc).
+ MCStreamer &OutStreamer;
+
+ /// Name-mangler for global names.
+ ///
+ Mangler *Mang;
+
/// doInitialization - Emit the file header and all of the global variables
/// for the module to the Mach-O file.
bool doInitialization(Module &M);
- bool runOnMachineFunction(MachineFunction &MF);
-
/// doFinalization - Now that the module has been completely processed, emit
/// the Mach-O file to 'O'.
bool doFinalization(Module &M);
- private:
-
- /// SectionList - This is the list of sections that we have emitted to the
- /// file. Once the file has been completely built, the segment load command
- /// SectionCommands are constructed from this info.
- std::vector<MachOSection*> SectionList;
-
- /// SectionLookup - This is a mapping from section name to SectionList entry
- std::map<std::string, MachOSection*> SectionLookup;
-
- /// GVSection - This is a mapping from a GlobalValue to a MachOSection,
- /// to aid in emitting relocations.
- std::map<GlobalValue*, MachOSection*> GVSection;
-
- /// GVOffset - This is a mapping from a GlobalValue to an offset from the
- /// start of the section in which the GV resides, to aid in emitting
- /// relocations.
- std::map<GlobalValue*, intptr_t> GVOffset;
-
- /// getSection - Return the section with the specified name, creating a new
- /// section if one does not already exist.
- MachOSection *getSection(const std::string &seg, const std::string &sect,
- unsigned Flags = 0);
-
- /// getTextSection - Return text section with different flags for code/data
- MachOSection *getTextSection(bool isCode = true);
-
- MachOSection *getDataSection() {
- return getSection("__DATA", "__data");
+ bool runOnMachineFunction(MachineFunction &MF);
+
+ public:
+ explicit MachOWriter(formatted_raw_ostream &O, TargetMachine &TM,
+ const MCAsmInfo *T, MCCodeEmitter *MCE);
+
+ virtual ~MachOWriter();
+
+ virtual const char *getPassName() const {
+ return "Mach-O Writer";
}
-
- MachOSection *getBSSSection();
- MachOSection *getConstSection(Constant *C);
- MachOSection *getJumpTableSection();
-
- /// MachOSymTab - This struct contains information about the offsets and
- /// size of symbol table information.
- /// segment.
- struct MachOSymTab {
- uint32_t cmd; // LC_SYMTAB
- uint32_t cmdsize; // sizeof( MachOSymTab )
- uint32_t symoff; // symbol table offset
- uint32_t nsyms; // number of symbol table entries
- uint32_t stroff; // string table offset
- uint32_t strsize; // string table size in bytes
-
- // Constants for the cmd field
- // see <mach-o/loader.h>
- enum { LC_SYMTAB = 0x02 // link-edit stab symbol table info
- };
-
- MachOSymTab() : cmd(LC_SYMTAB), cmdsize(6 * sizeof(uint32_t)), symoff(0),
- nsyms(0), stroff(0), strsize(0) { }
- };
-
- /// SymTab - The "stab" style symbol table information
- MachOSymTab SymTab;
- /// DySymTab - symbol table info for the dynamic link editor
- MachODySymTab DySymTab;
-
- protected:
-
- /// SymbolTable - This is the list of symbols we have emitted to the file.
- /// This actually gets rearranged before emission to the file (to put the
- /// local symbols first in the list).
- std::vector<MachOSym> SymbolTable;
-
- /// SymT - A buffer to hold the symbol table before we write it out at the
- /// appropriate location in the file.
- std::vector<unsigned char> SymT;
-
- /// StrT - A buffer to hold the string table before we write it out at the
- /// appropriate location in the file.
- std::vector<unsigned char> StrT;
-
- /// PendingSyms - This is a list of externally defined symbols that we have
- /// been asked to emit, but have not seen a reference to. When a reference
- /// is seen, the symbol will move from this list to the SymbolTable.
- std::vector<GlobalValue*> PendingGlobals;
-
- /// DynamicSymbolTable - This is just a vector of indices into
- /// SymbolTable to aid in emitting the DYSYMTAB load command.
- std::vector<unsigned> DynamicSymbolTable;
-
- static void InitMem(const Constant *C, uintptr_t Offset,
- const TargetData *TD, MachOSection* mos);
-
- private:
- void AddSymbolToSection(MachOSection *MOS, GlobalVariable *GV);
- void EmitGlobal(GlobalVariable *GV);
- void EmitHeaderAndLoadCommands();
- void EmitSections();
- void EmitRelocations();
- void BufferSymbolAndStringTable();
- void CalculateRelocations(MachOSection &MOS);
-
- // GetJTRelocation - Get a relocation a new BB relocation based
- // on target information.
- MachineRelocation GetJTRelocation(unsigned Offset,
- MachineBasicBlock *MBB) const;
-
- /// GetTargetRelocation - Returns the number of relocations.
- unsigned GetTargetRelocation(MachineRelocation &MR, unsigned FromIdx,
- unsigned ToAddr, unsigned ToIndex,
- OutputBuffer &RelocOut, OutputBuffer &SecOut,
- bool Scattered, bool Extern);
};
}
diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp
index e2ce642..9215bd5 100644
--- a/lib/CodeGen/MachineBasicBlock.cpp
+++ b/lib/CodeGen/MachineBasicBlock.cpp
@@ -378,7 +378,7 @@ bool MachineBasicBlock::canFallThrough() {
MachineBasicBlock *TBB = 0, *FBB = 0;
SmallVector<MachineOperand, 4> Cond;
const TargetInstrInfo *TII = getParent()->getTarget().getInstrInfo();
- if (TII->AnalyzeBranch(*this, TBB, FBB, Cond, true)) {
+ if (TII->AnalyzeBranch(*this, TBB, FBB, Cond)) {
// If we couldn't analyze the branch, examine the last instruction.
// If the block doesn't end in a known control barrier, assume fallthrough
// is possible. The isPredicable check is needed because this code can be
@@ -524,7 +524,26 @@ bool MachineBasicBlock::CorrectExtraCFGEdges(MachineBasicBlock *DestA,
return MadeChange;
}
+/// findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping
+/// any DEBUG_VALUE instructions. Return UnknownLoc if there is none.
+DebugLoc
+MachineBasicBlock::findDebugLoc(MachineBasicBlock::iterator &MBBI) {
+ DebugLoc DL;
+ MachineBasicBlock::iterator E = end();
+ if (MBBI != E) {
+ // Skip debug declarations, we don't want a DebugLoc from them.
+ MachineBasicBlock::iterator MBBI2 = MBBI;
+ while (MBBI2 != E &&
+ MBBI2->getOpcode()==TargetInstrInfo::DEBUG_VALUE)
+ MBBI2++;
+ if (MBBI2 != E)
+ DL = MBBI2->getDebugLoc();
+ }
+ return DL;
+}
+
void llvm::WriteAsOperand(raw_ostream &OS, const MachineBasicBlock *MBB,
bool t) {
OS << "BB#" << MBB->getNumber();
}
+
diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp
index ae9451c..1e3e314 100644
--- a/lib/CodeGen/MachineFunction.cpp
+++ b/lib/CodeGen/MachineFunction.cpp
@@ -26,6 +26,7 @@
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
+#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLowering.h"
@@ -426,12 +427,12 @@ unsigned MachineFunction::addLiveIn(unsigned PReg,
return VReg;
}
-/// getDebugLocTuple - Get the DebugLocTuple for a given DebugLoc object.
-DebugLocTuple MachineFunction::getDebugLocTuple(DebugLoc DL) const {
+/// getDILocation - Get the DILocation for a given DebugLoc object.
+DILocation MachineFunction::getDILocation(DebugLoc DL) const {
unsigned Idx = DL.getIndex();
assert(Idx < DebugLocInfo.DebugLocations.size() &&
"Invalid index into debug locations!");
- return DebugLocInfo.DebugLocations[Idx];
+ return DILocation(DebugLocInfo.DebugLocations[Idx]);
}
//===----------------------------------------------------------------------===//
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp
index cf3e3e1..ef2fcee 100644
--- a/lib/CodeGen/MachineInstr.cpp
+++ b/lib/CodeGen/MachineInstr.cpp
@@ -1162,6 +1162,13 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const {
if (FirstOp) FirstOp = false; else OS << ",";
OS << " ";
+ if (i < getDesc().NumOperands) {
+ const TargetOperandInfo &TOI = getDesc().OpInfo[i];
+ if (TOI.isPredicate())
+ OS << "pred:";
+ if (TOI.isOptionalDef())
+ OS << "opt:";
+ }
MO.print(OS, TM);
}
@@ -1189,17 +1196,17 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const {
// TODO: print InlinedAtLoc information
- DebugLocTuple DLT = MF->getDebugLocTuple(debugLoc);
- DIScope Scope(DLT.Scope);
+ DILocation DLT = MF->getDILocation(debugLoc);
+ DIScope Scope = DLT.getScope();
OS << " dbg:";
// Omit the directory, since it's usually long and uninteresting.
if (!Scope.isNull())
OS << Scope.getFilename();
else
OS << "<unknown>";
- OS << ':' << DLT.Line;
- if (DLT.Col != 0)
- OS << ':' << DLT.Col;
+ OS << ':' << DLT.getLineNumber();
+ if (DLT.getColumnNumber() != 0)
+ OS << ':' << DLT.getColumnNumber();
}
OS << "\n";
diff --git a/lib/CodeGen/Makefile b/lib/CodeGen/Makefile
index 4ab3e3c..8c0204c 100644
--- a/lib/CodeGen/Makefile
+++ b/lib/CodeGen/Makefile
@@ -11,6 +11,7 @@ LEVEL = ../..
LIBRARYNAME = LLVMCodeGen
PARALLEL_DIRS = SelectionDAG AsmPrinter
BUILD_ARCHIVE = 1
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/CodeGen/MaxStackAlignment.cpp b/lib/CodeGen/MaxStackAlignment.cpp
deleted file mode 100644
index d327cfa..0000000
--- a/lib/CodeGen/MaxStackAlignment.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-//===-- MaxStackAlignment.cpp - Compute the required stack alignment -- ---===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass looks for vector register usage and aligned local objects to
-// calculate the maximum required alignment for a function. This is used by
-// targets which support it to determine if dynamic stack realignment is
-// necessary.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/Passes.h"
-
-using namespace llvm;
-
-namespace {
- struct MaximalStackAlignmentCalculator : public MachineFunctionPass {
- static char ID;
- MaximalStackAlignmentCalculator() : MachineFunctionPass(&ID) {}
-
- virtual bool runOnMachineFunction(MachineFunction &MF) {
- MachineFrameInfo *FFI = MF.getFrameInfo();
- MachineRegisterInfo &RI = MF.getRegInfo();
-
- // Calculate max stack alignment of all already allocated stack objects.
- FFI->calculateMaxStackAlignment();
- unsigned MaxAlign = FFI->getMaxAlignment();
-
- // Be over-conservative: scan over all vreg defs and find whether vector
- // registers are used. If yes, there is probability that vector registers
- // will be spilled and thus the stack needs to be aligned properly.
- // FIXME: It would be better to only do this if a spill actually
- // happens rather than conseratively aligning the stack regardless.
- for (unsigned RegNum = TargetRegisterInfo::FirstVirtualRegister;
- RegNum < RI.getLastVirtReg(); ++RegNum)
- MaxAlign = std::max(MaxAlign, RI.getRegClass(RegNum)->getAlignment());
-
- if (FFI->getMaxAlignment() == MaxAlign)
- return false;
-
- FFI->setMaxAlignment(MaxAlign);
- return true;
- }
-
- virtual const char *getPassName() const {
- return "Stack Alignment Requirements Auto-Detector";
- }
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesCFG();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
- };
-
- char MaximalStackAlignmentCalculator::ID = 0;
-}
-
-FunctionPass*
-llvm::createMaxStackAlignmentCalculatorPass() {
- return new MaximalStackAlignmentCalculator();
-}
-
diff --git a/lib/CodeGen/OptimizeExts.cpp b/lib/CodeGen/OptimizeExts.cpp
index 625ff89..096f9d4 100644
--- a/lib/CodeGen/OptimizeExts.cpp
+++ b/lib/CodeGen/OptimizeExts.cpp
@@ -143,11 +143,23 @@ bool OptimizeExts::OptimizeInstr(MachineInstr *MI, MachineBasicBlock *MBB,
// Now replace all uses.
if (!Uses.empty()) {
+ SmallPtrSet<MachineBasicBlock*, 4> PHIBBs;
+ // Look for PHI uses of the extended result, we don't want to extend the
+ // liveness of a PHI input. It breaks all kinds of assumptions down
+ // stream. A PHI use is expected to be the kill of its source values.
+ UI = MRI->use_begin(DstReg);
+ for (MachineRegisterInfo::use_iterator UE = MRI->use_end(); UI != UE;
+ ++UI)
+ if (UI->getOpcode() == TargetInstrInfo::PHI)
+ PHIBBs.insert(UI->getParent());
+
const TargetRegisterClass *RC = MRI->getRegClass(SrcReg);
for (unsigned i = 0, e = Uses.size(); i != e; ++i) {
MachineOperand *UseMO = Uses[i];
MachineInstr *UseMI = UseMO->getParent();
MachineBasicBlock *UseMBB = UseMI->getParent();
+ if (PHIBBs.count(UseMBB))
+ continue;
unsigned NewVR = MRI->createVirtualRegister(RC);
BuildMI(*UseMBB, UseMI, UseMI->getDebugLoc(),
TII->get(TargetInstrInfo::EXTRACT_SUBREG), NewVR)
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 549527c..8883064 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -1088,6 +1088,26 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
if (Result.getNode()) return Result;
}
+ // fold (add x, shl(0 - y, n)) -> sub(x, shl(y, n))
+ if (N1.getOpcode() == ISD::SHL &&
+ N1.getOperand(0).getOpcode() == ISD::SUB)
+ if (ConstantSDNode *C =
+ dyn_cast<ConstantSDNode>(N1.getOperand(0).getOperand(0)))
+ if (C->getAPIntValue() == 0)
+ return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT, N0,
+ DAG.getNode(ISD::SHL, N->getDebugLoc(), VT,
+ N1.getOperand(0).getOperand(1),
+ N1.getOperand(1)));
+ if (N0.getOpcode() == ISD::SHL &&
+ N0.getOperand(0).getOpcode() == ISD::SUB)
+ if (ConstantSDNode *C =
+ dyn_cast<ConstantSDNode>(N0.getOperand(0).getOperand(0)))
+ if (C->getAPIntValue() == 0)
+ return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT, N1,
+ DAG.getNode(ISD::SHL, N->getDebugLoc(), VT,
+ N0.getOperand(0).getOperand(1),
+ N0.getOperand(1)));
+
return SDValue();
}
@@ -1176,6 +1196,9 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
if (N1C)
return DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N0,
DAG.getConstant(-N1C->getAPIntValue(), VT));
+ // Canonicalize (sub -1, x) -> ~x, i.e. (xor x, -1)
+ if (N0C && N0C->isAllOnesValue())
+ return DAG.getNode(ISD::XOR, N->getDebugLoc(), VT, N1, N0);
// fold (A+B)-A -> B
if (N0.getOpcode() == ISD::ADD && N0.getOperand(0) == N1)
return N0.getOperand(1);
diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
index 4868c9e..dc7d82d 100644
--- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
+++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
@@ -35,7 +35,6 @@
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index 669d414..9c50936 100644
--- a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -24,7 +24,6 @@
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
diff --git a/lib/CodeGen/SelectionDAG/Makefile b/lib/CodeGen/SelectionDAG/Makefile
index 73f0b5d..4706e68 100644
--- a/lib/CodeGen/SelectionDAG/Makefile
+++ b/lib/CodeGen/SelectionDAG/Makefile
@@ -6,8 +6,9 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMSelectionDAG
-PARALLEL_DIRS =
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
index 0c3c974c..ad8630a 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
@@ -22,7 +22,6 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
index 1ad7919..dea5993 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -46,6 +46,11 @@ static RegisterScheduler
tdrListrDAGScheduler("list-tdrr",
"Top-down register reduction list scheduling",
createTDRRListDAGScheduler);
+static RegisterScheduler
+ sourceListDAGScheduler("source",
+ "Similar to list-burr but schedules in source "
+ "order when possible",
+ createSourceListDAGScheduler);
namespace {
//===----------------------------------------------------------------------===//
@@ -931,6 +936,16 @@ namespace {
bool operator()(const SUnit* left, const SUnit* right) const;
};
+
+ struct src_ls_rr_sort : public std::binary_function<SUnit*, SUnit*, bool> {
+ RegReductionPriorityQueue<src_ls_rr_sort> *SPQ;
+ src_ls_rr_sort(RegReductionPriorityQueue<src_ls_rr_sort> *spq)
+ : SPQ(spq) {}
+ src_ls_rr_sort(const src_ls_rr_sort &RHS)
+ : SPQ(RHS.SPQ) {}
+
+ bool operator()(const SUnit* left, const SUnit* right) const;
+ };
} // end anonymous namespace
/// CalcNodeSethiUllmanNumber - Compute Sethi Ullman number.
@@ -981,9 +996,9 @@ namespace {
public:
RegReductionPriorityQueue(const TargetInstrInfo *tii,
- const TargetRegisterInfo *tri) :
- Queue(SF(this)), currentQueueId(0),
- TII(tii), TRI(tri), scheduleDAG(NULL) {}
+ const TargetRegisterInfo *tri)
+ : Queue(SF(this)), currentQueueId(0),
+ TII(tii), TRI(tri), scheduleDAG(NULL) {}
void initNodes(std::vector<SUnit> &sunits) {
SUnits = &sunits;
@@ -1089,6 +1104,9 @@ namespace {
typedef RegReductionPriorityQueue<td_ls_rr_sort>
TDRegReductionPriorityQueue;
+
+ typedef RegReductionPriorityQueue<src_ls_rr_sort>
+ SrcRegReductionPriorityQueue;
}
/// closestSucc - Returns the scheduled cycle of the successor which is
@@ -1122,16 +1140,9 @@ static unsigned calcMaxScratches(const SUnit *SU) {
return Scratches;
}
-// Bottom up
-bool bu_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const {
- unsigned LOrder = SPQ->getNodeOrdering(left);
- unsigned ROrder = SPQ->getNodeOrdering(right);
-
- // Prefer an ordering where the lower the non-zero order number, the higher
- // the preference.
- if ((LOrder || ROrder) && LOrder != ROrder)
- return LOrder != 0 && (LOrder < ROrder || ROrder == 0);
-
+template <typename RRSort>
+static bool BURRSort(const SUnit *left, const SUnit *right,
+ const RegReductionPriorityQueue<RRSort> *SPQ) {
unsigned LPriority = SPQ->getNodePriority(left);
unsigned RPriority = SPQ->getNodePriority(right);
if (LPriority != RPriority)
@@ -1176,6 +1187,24 @@ bool bu_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const {
return (left->NodeQueueId > right->NodeQueueId);
}
+// Bottom up
+bool bu_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const {
+ return BURRSort(left, right, SPQ);
+}
+
+// Source order, otherwise bottom up.
+bool src_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const{
+ unsigned LOrder = SPQ->getNodeOrdering(left);
+ unsigned ROrder = SPQ->getNodeOrdering(right);
+
+ // Prefer an ordering where the lower the non-zero order number, the higher
+ // the preference.
+ if ((LOrder || ROrder) && LOrder != ROrder)
+ return LOrder != 0 && (LOrder < ROrder || ROrder == 0);
+
+ return BURRSort(left, right, SPQ);
+}
+
template<class SF>
bool
RegReductionPriorityQueue<SF>::canClobber(const SUnit *SU, const SUnit *Op) {
@@ -1196,7 +1225,6 @@ RegReductionPriorityQueue<SF>::canClobber(const SUnit *SU, const SUnit *Op) {
return false;
}
-
/// hasCopyToRegUse - Return true if SU has a value successor that is a
/// CopyToReg node.
static bool hasCopyToRegUse(const SUnit *SU) {
@@ -1544,3 +1572,17 @@ llvm::createTDRRListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level) {
PQ->setScheduleDAG(SD);
return SD;
}
+
+llvm::ScheduleDAGSDNodes *
+llvm::createSourceListDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level) {
+ const TargetMachine &TM = IS->TM;
+ const TargetInstrInfo *TII = TM.getInstrInfo();
+ const TargetRegisterInfo *TRI = TM.getRegisterInfo();
+
+ SrcRegReductionPriorityQueue *PQ = new SrcRegReductionPriorityQueue(TII, TRI);
+
+ ScheduleDAGRRList *SD =
+ new ScheduleDAGRRList(*IS->MF, true, PQ);
+ PQ->setScheduleDAG(SD);
+ return SD;
+}
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
index aaaa2b3..b51c61b 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
@@ -20,10 +20,16 @@
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSubtarget.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
+STATISTIC(LoadsClustered, "Number of loads clustered together");
+
ScheduleDAGSDNodes::ScheduleDAGSDNodes(MachineFunction &mf)
: ScheduleDAG(mf) {
}
@@ -75,6 +81,122 @@ static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
}
}
+static void AddFlags(SDNode *N, SDValue Flag, bool AddFlag,
+ SelectionDAG *DAG) {
+ SmallVector<EVT, 4> VTs;
+ for (unsigned i = 0, e = N->getNumValues(); i != e; ++i)
+ VTs.push_back(N->getValueType(i));
+ if (AddFlag)
+ VTs.push_back(MVT::Flag);
+ SmallVector<SDValue, 4> Ops;
+ for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
+ Ops.push_back(N->getOperand(i));
+ if (Flag.getNode())
+ Ops.push_back(Flag);
+ SDVTList VTList = DAG->getVTList(&VTs[0], VTs.size());
+ DAG->MorphNodeTo(N, N->getOpcode(), VTList, &Ops[0], Ops.size());
+}
+
+/// ClusterNeighboringLoads - Force nearby loads together by "flagging" them.
+/// This function finds loads of the same base and different offsets. If the
+/// offsets are not far apart (target specific), it add MVT::Flag inputs and
+/// outputs to ensure they are scheduled together and in order. This
+/// optimization may benefit some targets by improving cache locality.
+void ScheduleDAGSDNodes::ClusterNeighboringLoads() {
+ SmallPtrSet<SDNode*, 16> Visited;
+ SmallVector<int64_t, 4> Offsets;
+ DenseMap<long long, SDNode*> O2SMap; // Map from offset to SDNode.
+ for (SelectionDAG::allnodes_iterator NI = DAG->allnodes_begin(),
+ E = DAG->allnodes_end(); NI != E; ++NI) {
+ SDNode *Node = &*NI;
+ if (!Node || !Node->isMachineOpcode())
+ continue;
+
+ unsigned Opc = Node->getMachineOpcode();
+ const TargetInstrDesc &TID = TII->get(Opc);
+ if (!TID.mayLoad())
+ continue;
+
+ SDNode *Chain = 0;
+ unsigned NumOps = Node->getNumOperands();
+ if (Node->getOperand(NumOps-1).getValueType() == MVT::Other)
+ Chain = Node->getOperand(NumOps-1).getNode();
+ if (!Chain)
+ continue;
+
+ // Look for other loads of the same chain. Find loads that are loading from
+ // the same base pointer and different offsets.
+ Visited.clear();
+ Offsets.clear();
+ O2SMap.clear();
+ bool Cluster = false;
+ SDNode *Base = Node;
+ int64_t BaseOffset;
+ for (SDNode::use_iterator I = Chain->use_begin(), E = Chain->use_end();
+ I != E; ++I) {
+ SDNode *User = *I;
+ if (User == Node || !Visited.insert(User))
+ continue;
+ int64_t Offset1, Offset2;
+ if (!TII->areLoadsFromSameBasePtr(Base, User, Offset1, Offset2) ||
+ Offset1 == Offset2)
+ // FIXME: Should be ok if they addresses are identical. But earlier
+ // optimizations really should have eliminated one of the loads.
+ continue;
+ if (O2SMap.insert(std::make_pair(Offset1, Base)).second)
+ Offsets.push_back(Offset1);
+ O2SMap.insert(std::make_pair(Offset2, User));
+ Offsets.push_back(Offset2);
+ if (Offset2 < Offset1) {
+ Base = User;
+ BaseOffset = Offset2;
+ } else {
+ BaseOffset = Offset1;
+ }
+ Cluster = true;
+ }
+
+ if (!Cluster)
+ continue;
+
+ // Sort them in increasing order.
+ std::sort(Offsets.begin(), Offsets.end());
+
+ // Check if the loads are close enough.
+ SmallVector<SDNode*, 4> Loads;
+ unsigned NumLoads = 0;
+ int64_t BaseOff = Offsets[0];
+ SDNode *BaseLoad = O2SMap[BaseOff];
+ Loads.push_back(BaseLoad);
+ for (unsigned i = 1, e = Offsets.size(); i != e; ++i) {
+ int64_t Offset = Offsets[i];
+ SDNode *Load = O2SMap[Offset];
+ if (!TII->shouldScheduleLoadsNear(BaseLoad, Load, BaseOff, Offset,
+ NumLoads))
+ break; // Stop right here. Ignore loads that are further away.
+ Loads.push_back(Load);
+ ++NumLoads;
+ }
+
+ if (NumLoads == 0)
+ continue;
+
+ // Cluster loads by adding MVT::Flag outputs and inputs. This also
+ // ensure they are scheduled in order of increasing addresses.
+ SDNode *Lead = Loads[0];
+ AddFlags(Lead, SDValue(0,0), true, DAG);
+ SDValue InFlag = SDValue(Lead, Lead->getNumValues()-1);
+ for (unsigned i = 1, e = Loads.size(); i != e; ++i) {
+ bool OutFlag = i < e-1;
+ SDNode *Load = Loads[i];
+ AddFlags(Load, InFlag, OutFlag, DAG);
+ if (OutFlag)
+ InFlag = SDValue(Load, Load->getNumValues()-1);
+ ++LoadsClustered;
+ }
+ }
+}
+
void ScheduleDAGSDNodes::BuildSchedUnits() {
// During scheduling, the NodeId field of SDNode is used to map SDNodes
// to their associated SUnits by holding SUnits table indices. A value
@@ -232,6 +354,8 @@ void ScheduleDAGSDNodes::AddSchedEdges() {
/// excludes nodes that aren't interesting to scheduling, and represents
/// flagged together nodes with a single SUnit.
void ScheduleDAGSDNodes::BuildSchedGraph(AliasAnalysis *AA) {
+ // Cluster loads from "near" addresses into combined SUnits.
+ ClusterNeighboringLoads();
// Populate the SUnits array.
BuildSchedUnits();
// Compute all the scheduling dependencies between nodes.
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h
index ebb31ac..6b829b6 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h
@@ -108,6 +108,10 @@ namespace llvm {
virtual void getCustomGraphFeatures(GraphWriter<ScheduleDAG*> &GW) const;
private:
+ /// ClusterNeighboringLoads - Cluster loads from "near" addresses into
+ /// combined SUnits.
+ void ClusterNeighboringLoads();
+
/// BuildSchedUnits, AddSchedEdges - Helper functions for BuildSchedGraph.
void BuildSchedUnits();
void AddSchedEdges();
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index cb1a0d6..f1b6f1e 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -593,7 +593,7 @@ void SelectionDAG::DeallocateNode(SDNode *N) {
NodeAllocator.Deallocate(AllNodes.remove(N));
// Remove the ordering of this node.
- if (Ordering) Ordering->remove(N);
+ Ordering->remove(N);
}
/// RemoveNodeFromCSEMaps - Take the specified node out of the CSE map that
@@ -790,8 +790,7 @@ SelectionDAG::SelectionDAG(TargetLowering &tli, FunctionLoweringInfo &fli)
getVTList(MVT::Other)),
Root(getEntryNode()), Ordering(0) {
AllNodes.push_back(&EntryNode);
- if (DisableScheduling)
- Ordering = new SDNodeOrdering();
+ Ordering = new SDNodeOrdering();
}
void SelectionDAG::init(MachineFunction &mf, MachineModuleInfo *mmi,
@@ -830,8 +829,7 @@ void SelectionDAG::clear() {
EntryNode.UseList = 0;
AllNodes.push_back(&EntryNode);
Root = getEntryNode();
- if (DisableScheduling)
- Ordering = new SDNodeOrdering();
+ Ordering = new SDNodeOrdering();
}
SDValue SelectionDAG::getSExtOrTrunc(SDValue Op, DebugLoc DL, EVT VT) {
@@ -5172,6 +5170,7 @@ unsigned SelectionDAG::AssignTopologicalOrder() {
// count of outstanding operands.
for (allnodes_iterator I = allnodes_begin(),E = allnodes_end(); I != E; ) {
SDNode *N = I++;
+ checkForCycles(N);
unsigned Degree = N->getNumOperands();
if (Degree == 0) {
// A node with no uses, add it to the result array immediately.
@@ -5179,6 +5178,7 @@ unsigned SelectionDAG::AssignTopologicalOrder() {
allnodes_iterator Q = N;
if (Q != SortedPos)
SortedPos = AllNodes.insert(SortedPos, AllNodes.remove(Q));
+ assert(SortedPos != AllNodes.end() && "Overran node list");
++SortedPos;
} else {
// Temporarily use the Node Id as scratch space for the degree count.
@@ -5190,22 +5190,34 @@ unsigned SelectionDAG::AssignTopologicalOrder() {
// such that by the time the end is reached all nodes will be sorted.
for (allnodes_iterator I = allnodes_begin(),E = allnodes_end(); I != E; ++I) {
SDNode *N = I;
+ checkForCycles(N);
+ // N is in sorted position, so all its uses have one less operand
+ // that needs to be sorted.
for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end();
UI != UE; ++UI) {
SDNode *P = *UI;
unsigned Degree = P->getNodeId();
+ assert(Degree != 0 && "Invalid node degree");
--Degree;
if (Degree == 0) {
// All of P's operands are sorted, so P may sorted now.
P->setNodeId(DAGSize++);
if (P != SortedPos)
SortedPos = AllNodes.insert(SortedPos, AllNodes.remove(P));
+ assert(SortedPos != AllNodes.end() && "Overran node list");
++SortedPos;
} else {
// Update P's outstanding operand count.
P->setNodeId(Degree);
}
}
+ if (I == SortedPos) {
+ allnodes_iterator J = I;
+ SDNode *S = ++J;
+ dbgs() << "Offending node:\n";
+ S->dumprFull();
+ assert(0 && "Overran sorted position");
+ }
}
assert(SortedPos == AllNodes.end() &&
@@ -5227,14 +5239,13 @@ unsigned SelectionDAG::AssignTopologicalOrder() {
/// AssignOrdering - Assign an order to the SDNode.
void SelectionDAG::AssignOrdering(SDNode *SD, unsigned Order) {
assert(SD && "Trying to assign an order to a null node!");
- if (Ordering)
- Ordering->add(SD, Order);
+ Ordering->add(SD, Order);
}
/// GetOrdering - Get the order for the SDNode.
unsigned SelectionDAG::GetOrdering(const SDNode *SD) const {
assert(SD && "Trying to get the order of a null node!");
- return Ordering ? Ordering->getOrder(SD) : 0;
+ return Ordering->getOrder(SD);
}
@@ -5893,6 +5904,45 @@ void SDNode::print(raw_ostream &OS, const SelectionDAG *G) const {
print_details(OS, G);
}
+static void printrWithDepthHelper(raw_ostream &OS, const SDNode *N,
+ const SelectionDAG *G, unsigned depth,
+ unsigned indent)
+{
+ if (depth == 0)
+ return;
+
+ OS.indent(indent);
+
+ N->print(OS, G);
+
+ if (depth < 1)
+ return;
+
+ for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
+ OS << '\n';
+ printrWithDepthHelper(OS, N->getOperand(i).getNode(), G, depth-1, indent+2);
+ }
+}
+
+void SDNode::printrWithDepth(raw_ostream &OS, const SelectionDAG *G,
+ unsigned depth) const {
+ printrWithDepthHelper(OS, this, G, depth, 0);
+}
+
+void SDNode::printrFull(raw_ostream &OS, const SelectionDAG *G) const {
+ // Don't print impossibly deep things.
+ printrWithDepth(OS, G, 100);
+}
+
+void SDNode::dumprWithDepth(const SelectionDAG *G, unsigned depth) const {
+ printrWithDepth(dbgs(), G, depth);
+}
+
+void SDNode::dumprFull(const SelectionDAG *G) const {
+ // Don't print impossibly deep things.
+ dumprWithDepth(G, 100);
+}
+
static void DumpNodes(const SDNode *N, unsigned indent, const SelectionDAG *G) {
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
if (N->getOperand(i).getNode()->hasOneUse())
@@ -6228,3 +6278,35 @@ bool ShuffleVectorSDNode::isSplatMask(const int *Mask, EVT VT) {
return false;
return true;
}
+
+static void checkForCyclesHelper(const SDNode *N,
+ std::set<const SDNode *> &visited) {
+ if (visited.find(N) != visited.end()) {
+ dbgs() << "Offending node:\n";
+ N->dumprFull();
+ assert(0 && "Detected cycle in SelectionDAG");
+ }
+
+ std::set<const SDNode*>::iterator i;
+ bool inserted;
+
+ tie(i, inserted) = visited.insert(N);
+ assert(inserted && "Missed cycle");
+
+ for(unsigned i = 0; i < N->getNumOperands(); ++i) {
+ checkForCyclesHelper(N->getOperand(i).getNode(), visited);
+ }
+ visited.erase(i);
+}
+
+void llvm::checkForCycles(const llvm::SDNode *N) {
+#ifdef XDEBUG
+ assert(N && "Checking nonexistant SDNode");
+ std::set<const SDNode *> visited;
+ checkForCyclesHelper(N, visited);
+#endif
+}
+
+void llvm::checkForCycles(const llvm::SelectionDAG *DAG) {
+ checkForCycles(DAG->getRoot().getNode());
+}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 5e3a3b5..23c7059 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -176,7 +176,7 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
assert(NumParts > 0 && "No parts to assemble!");
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
SDValue Val = Parts[0];
- if (DisableScheduling) DAG.AssignOrdering(Val.getNode(), Order);
+ DAG.AssignOrdering(Val.getNode(), Order);
if (NumParts > 1) {
// Assemble the value from multiple parts.
@@ -209,11 +209,9 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
Val = DAG.getNode(ISD::BUILD_PAIR, dl, RoundVT, Lo, Hi);
- if (DisableScheduling) {
- DAG.AssignOrdering(Lo.getNode(), Order);
- DAG.AssignOrdering(Hi.getNode(), Order);
- DAG.AssignOrdering(Val.getNode(), Order);
- }
+ DAG.AssignOrdering(Lo.getNode(), Order);
+ DAG.AssignOrdering(Hi.getNode(), Order);
+ DAG.AssignOrdering(Val.getNode(), Order);
if (RoundParts < NumParts) {
// Assemble the trailing non-power-of-2 part.
@@ -228,15 +226,15 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
std::swap(Lo, Hi);
EVT TotalVT = EVT::getIntegerVT(*DAG.getContext(), NumParts * PartBits);
Hi = DAG.getNode(ISD::ANY_EXTEND, dl, TotalVT, Hi);
- if (DisableScheduling) DAG.AssignOrdering(Hi.getNode(), Order);
+ DAG.AssignOrdering(Hi.getNode(), Order);
Hi = DAG.getNode(ISD::SHL, dl, TotalVT, Hi,
DAG.getConstant(Lo.getValueType().getSizeInBits(),
TLI.getPointerTy()));
- if (DisableScheduling) DAG.AssignOrdering(Hi.getNode(), Order);
+ DAG.AssignOrdering(Hi.getNode(), Order);
Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, TotalVT, Lo);
- if (DisableScheduling) DAG.AssignOrdering(Lo.getNode(), Order);
+ DAG.AssignOrdering(Lo.getNode(), Order);
Val = DAG.getNode(ISD::OR, dl, TotalVT, Lo, Hi);
- if (DisableScheduling) DAG.AssignOrdering(Val.getNode(), Order);
+ DAG.AssignOrdering(Val.getNode(), Order);
}
} else if (ValueVT.isVector()) {
// Handle a multi-element vector.
@@ -277,7 +275,7 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
Val = DAG.getNode(IntermediateVT.isVector() ?
ISD::CONCAT_VECTORS : ISD::BUILD_VECTOR, dl,
ValueVT, &Ops[0], NumIntermediates);
- if (DisableScheduling) DAG.AssignOrdering(Val.getNode(), Order);
+ DAG.AssignOrdering(Val.getNode(), Order);
} else if (PartVT.isFloatingPoint()) {
// FP split into multiple FP parts (for ppcf128)
assert(ValueVT == EVT(MVT::ppcf128) && PartVT == EVT(MVT::f64) &&
@@ -289,11 +287,9 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
std::swap(Lo, Hi);
Val = DAG.getNode(ISD::BUILD_PAIR, dl, ValueVT, Lo, Hi);
- if (DisableScheduling) {
- DAG.AssignOrdering(Hi.getNode(), Order);
- DAG.AssignOrdering(Lo.getNode(), Order);
- DAG.AssignOrdering(Val.getNode(), Order);
- }
+ DAG.AssignOrdering(Hi.getNode(), Order);
+ DAG.AssignOrdering(Lo.getNode(), Order);
+ DAG.AssignOrdering(Val.getNode(), Order);
} else {
// FP split into integer parts (soft fp)
assert(ValueVT.isFloatingPoint() && PartVT.isInteger() &&
@@ -312,8 +308,7 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
if (PartVT.isVector()) {
assert(ValueVT.isVector() && "Unknown vector conversion!");
SDValue Res = DAG.getNode(ISD::BIT_CONVERT, dl, ValueVT, Val);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), Order);
+ DAG.AssignOrdering(Res.getNode(), Order);
return Res;
}
@@ -322,8 +317,7 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
ValueVT.getVectorNumElements() == 1 &&
"Only trivial scalar-to-vector conversions should get here!");
SDValue Res = DAG.getNode(ISD::BUILD_VECTOR, dl, ValueVT, Val);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), Order);
+ DAG.AssignOrdering(Res.getNode(), Order);
return Res;
}
@@ -336,13 +330,13 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
if (AssertOp != ISD::DELETED_NODE)
Val = DAG.getNode(AssertOp, dl, PartVT, Val,
DAG.getValueType(ValueVT));
- if (DisableScheduling) DAG.AssignOrdering(Val.getNode(), Order);
+ DAG.AssignOrdering(Val.getNode(), Order);
Val = DAG.getNode(ISD::TRUNCATE, dl, ValueVT, Val);
- if (DisableScheduling) DAG.AssignOrdering(Val.getNode(), Order);
+ DAG.AssignOrdering(Val.getNode(), Order);
return Val;
} else {
Val = DAG.getNode(ISD::ANY_EXTEND, dl, ValueVT, Val);
- if (DisableScheduling) DAG.AssignOrdering(Val.getNode(), Order);
+ DAG.AssignOrdering(Val.getNode(), Order);
return Val;
}
}
@@ -352,18 +346,18 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
// FP_ROUND's are always exact here.
Val = DAG.getNode(ISD::FP_ROUND, dl, ValueVT, Val,
DAG.getIntPtrConstant(1));
- if (DisableScheduling) DAG.AssignOrdering(Val.getNode(), Order);
+ DAG.AssignOrdering(Val.getNode(), Order);
return Val;
}
Val = DAG.getNode(ISD::FP_EXTEND, dl, ValueVT, Val);
- if (DisableScheduling) DAG.AssignOrdering(Val.getNode(), Order);
+ DAG.AssignOrdering(Val.getNode(), Order);
return Val;
}
if (PartVT.getSizeInBits() == ValueVT.getSizeInBits()) {
Val = DAG.getNode(ISD::BIT_CONVERT, dl, ValueVT, Val);
- if (DisableScheduling) DAG.AssignOrdering(Val.getNode(), Order);
+ DAG.AssignOrdering(Val.getNode(), Order);
return Val;
}
@@ -420,7 +414,7 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
}
}
- if (DisableScheduling) DAG.AssignOrdering(Val.getNode(), Order);
+ DAG.AssignOrdering(Val.getNode(), Order);
// The value may have changed - recompute ValueVT.
ValueVT = Val.getValueType();
@@ -455,10 +449,8 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
ValueVT = EVT::getIntegerVT(*DAG.getContext(), NumParts * PartBits);
Val = DAG.getNode(ISD::TRUNCATE, dl, ValueVT, Val);
- if (DisableScheduling) {
- DAG.AssignOrdering(OddVal.getNode(), Order);
- DAG.AssignOrdering(Val.getNode(), Order);
- }
+ DAG.AssignOrdering(OddVal.getNode(), Order);
+ DAG.AssignOrdering(Val.getNode(), Order);
}
// The number of parts is a power of 2. Repeatedly bisect the value using
@@ -468,8 +460,7 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
ValueVT.getSizeInBits()),
Val);
- if (DisableScheduling)
- DAG.AssignOrdering(Parts[0].getNode(), Order);
+ DAG.AssignOrdering(Parts[0].getNode(), Order);
for (unsigned StepSize = NumParts; StepSize > 1; StepSize /= 2) {
for (unsigned i = 0; i < NumParts; i += StepSize) {
@@ -485,20 +476,16 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
ThisVT, Part0,
DAG.getConstant(0, PtrVT));
- if (DisableScheduling) {
- DAG.AssignOrdering(Part0.getNode(), Order);
- DAG.AssignOrdering(Part1.getNode(), Order);
- }
+ DAG.AssignOrdering(Part0.getNode(), Order);
+ DAG.AssignOrdering(Part1.getNode(), Order);
if (ThisBits == PartBits && ThisVT != PartVT) {
Part0 = DAG.getNode(ISD::BIT_CONVERT, dl,
PartVT, Part0);
Part1 = DAG.getNode(ISD::BIT_CONVERT, dl,
PartVT, Part1);
- if (DisableScheduling) {
- DAG.AssignOrdering(Part0.getNode(), Order);
- DAG.AssignOrdering(Part1.getNode(), Order);
- }
+ DAG.AssignOrdering(Part0.getNode(), Order);
+ DAG.AssignOrdering(Part1.getNode(), Order);
}
}
}
@@ -524,9 +511,7 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
}
}
- if (DisableScheduling)
- DAG.AssignOrdering(Val.getNode(), Order);
-
+ DAG.AssignOrdering(Val.getNode(), Order);
Parts[0] = Val;
return;
}
@@ -555,8 +540,7 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, unsigned Order,
IntermediateVT, Val,
DAG.getConstant(i, PtrVT));
- if (DisableScheduling)
- DAG.AssignOrdering(Ops[i].getNode(), Order);
+ DAG.AssignOrdering(Ops[i].getNode(), Order);
}
// Split the intermediate operands into legal parts.
@@ -717,8 +701,7 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) {
SDValue Res = DAG.getMergeValues(&Constants[0], Constants.size(),
getCurDebugLoc());
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return Res;
}
@@ -744,8 +727,7 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) {
SDValue Res = DAG.getMergeValues(&Constants[0], NumElts,
getCurDebugLoc());
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return Res;
}
@@ -776,9 +758,7 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) {
// Create a BUILD_VECTOR node.
SDValue Res = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(),
VT, &Ops[0], Ops.size());
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
-
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return NodeMap[V] = Res;
}
@@ -800,18 +780,19 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) {
SDNodeOrder, Chain, NULL);
}
-/// Get the EVTs and ArgFlags collections that represent the return type
-/// of the given function. This does not require a DAG or a return value, and
-/// is suitable for use before any DAGs for the function are constructed.
+/// Get the EVTs and ArgFlags collections that represent the legalized return
+/// type of the given function. This does not require a DAG or a return value,
+/// and is suitable for use before any DAGs for the function are constructed.
static void getReturnInfo(const Type* ReturnType,
Attributes attr, SmallVectorImpl<EVT> &OutVTs,
SmallVectorImpl<ISD::ArgFlagsTy> &OutFlags,
TargetLowering &TLI,
SmallVectorImpl<uint64_t> *Offsets = 0) {
SmallVector<EVT, 4> ValueVTs;
- ComputeValueVTs(TLI, ReturnType, ValueVTs, Offsets);
+ ComputeValueVTs(TLI, ReturnType, ValueVTs);
unsigned NumValues = ValueVTs.size();
- if ( NumValues == 0 ) return;
+ if (NumValues == 0) return;
+ unsigned Offset = 0;
for (unsigned j = 0, f = NumValues; j != f; ++j) {
EVT VT = ValueVTs[j];
@@ -834,6 +815,9 @@ static void getReturnInfo(const Type* ReturnType,
unsigned NumParts = TLI.getNumRegisters(ReturnType->getContext(), VT);
EVT PartVT = TLI.getRegisterType(ReturnType->getContext(), VT);
+ unsigned PartSize = TLI.getTargetData()->getTypeAllocSize(
+ PartVT.getTypeForEVT(ReturnType->getContext()));
+
// 'inreg' on function refers to return value
ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy();
if (attr & Attribute::InReg)
@@ -848,6 +832,11 @@ static void getReturnInfo(const Type* ReturnType,
for (unsigned i = 0; i < NumParts; ++i) {
OutVTs.push_back(PartVT);
OutFlags.push_back(Flags);
+ if (Offsets)
+ {
+ Offsets->push_back(Offset);
+ Offset += PartSize;
+ }
}
}
}
@@ -886,17 +875,14 @@ void SelectionDAGBuilder::visitRet(ReturnInst &I) {
SDValue(RetOp.getNode(), RetOp.getResNo() + i),
Add, NULL, Offsets[i], false, 0);
- if (DisableScheduling) {
- DAG.AssignOrdering(Add.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Chains[i].getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(Add.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Chains[i].getNode(), SDNodeOrder);
}
Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(),
MVT::Other, &Chains[0], NumValues);
- if (DisableScheduling)
- DAG.AssignOrdering(Chain.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Chain.getNode(), SDNodeOrder);
} else {
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
SmallVector<EVT, 4> ValueVTs;
@@ -962,9 +948,7 @@ void SelectionDAGBuilder::visitRet(ReturnInst &I) {
// Update the DAG with the new chain value resulting from return lowering.
DAG.setRoot(Chain);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Chain.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Chain.getNode(), SDNodeOrder);
}
/// CopyToExportRegsIfNeeded - If the given value has virtual registers
@@ -1230,9 +1214,7 @@ void SelectionDAGBuilder::visitBr(BranchInst &I) {
MVT::Other, getControlRoot(),
DAG.getBasicBlock(Succ0MBB));
DAG.setRoot(V);
-
- if (DisableScheduling)
- DAG.AssignOrdering(V.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(V.getNode(), SDNodeOrder);
}
return;
@@ -1339,8 +1321,7 @@ void SelectionDAGBuilder::visitSwitchCase(CaseBlock &CB) {
}
}
- if (DisableScheduling)
- DAG.AssignOrdering(Cond.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Cond.getNode(), SDNodeOrder);
// Update successor info
CurMBB->addSuccessor(CB.TrueBB);
@@ -1359,17 +1340,13 @@ void SelectionDAGBuilder::visitSwitchCase(CaseBlock &CB) {
std::swap(CB.TrueBB, CB.FalseBB);
SDValue True = DAG.getConstant(1, Cond.getValueType());
Cond = DAG.getNode(ISD::XOR, dl, Cond.getValueType(), Cond, True);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Cond.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Cond.getNode(), SDNodeOrder);
}
SDValue BrCond = DAG.getNode(ISD::BRCOND, dl,
MVT::Other, getControlRoot(), Cond,
DAG.getBasicBlock(CB.TrueBB));
-
- if (DisableScheduling)
- DAG.AssignOrdering(BrCond.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(BrCond.getNode(), SDNodeOrder);
// If the branch was constant folded, fix up the CFG.
if (BrCond.getOpcode() == ISD::BR) {
@@ -1383,8 +1360,7 @@ void SelectionDAGBuilder::visitSwitchCase(CaseBlock &CB) {
BrCond = DAG.getNode(ISD::BR, dl, MVT::Other, BrCond,
DAG.getBasicBlock(CB.FalseBB));
- if (DisableScheduling)
- DAG.AssignOrdering(BrCond.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(BrCond.getNode(), SDNodeOrder);
}
}
@@ -1404,11 +1380,9 @@ void SelectionDAGBuilder::visitJumpTable(JumpTable &JT) {
Table, Index);
DAG.setRoot(BrJumpTable);
- if (DisableScheduling) {
- DAG.AssignOrdering(Index.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Table.getNode(), SDNodeOrder);
- DAG.AssignOrdering(BrJumpTable.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(Index.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Table.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(BrJumpTable.getNode(), SDNodeOrder);
}
/// visitJumpTableHeader - This function emits necessary code to produce index
@@ -1443,12 +1417,10 @@ void SelectionDAGBuilder::visitJumpTableHeader(JumpTable &JT,
DAG.getConstant(JTH.Last-JTH.First,VT),
ISD::SETUGT);
- if (DisableScheduling) {
- DAG.AssignOrdering(Sub.getNode(), SDNodeOrder);
- DAG.AssignOrdering(SwitchOp.getNode(), SDNodeOrder);
- DAG.AssignOrdering(CopyTo.getNode(), SDNodeOrder);
- DAG.AssignOrdering(CMP.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(Sub.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(SwitchOp.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(CopyTo.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(CMP.getNode(), SDNodeOrder);
// Set NextBlock to be the MBB immediately after the current one, if any.
// This is used to avoid emitting unnecessary branches to the next block.
@@ -1462,15 +1434,12 @@ void SelectionDAGBuilder::visitJumpTableHeader(JumpTable &JT,
MVT::Other, CopyTo, CMP,
DAG.getBasicBlock(JT.Default));
- if (DisableScheduling)
- DAG.AssignOrdering(BrCond.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(BrCond.getNode(), SDNodeOrder);
if (JT.MBB != NextBlock) {
BrCond = DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, BrCond,
DAG.getBasicBlock(JT.MBB));
-
- if (DisableScheduling)
- DAG.AssignOrdering(BrCond.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(BrCond.getNode(), SDNodeOrder);
}
DAG.setRoot(BrCond);
@@ -1498,12 +1467,10 @@ void SelectionDAGBuilder::visitBitTestHeader(BitTestBlock &B) {
SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), getCurDebugLoc(),
B.Reg, ShiftOp);
- if (DisableScheduling) {
- DAG.AssignOrdering(Sub.getNode(), SDNodeOrder);
- DAG.AssignOrdering(RangeCmp.getNode(), SDNodeOrder);
- DAG.AssignOrdering(ShiftOp.getNode(), SDNodeOrder);
- DAG.AssignOrdering(CopyTo.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(Sub.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(RangeCmp.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(ShiftOp.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(CopyTo.getNode(), SDNodeOrder);
// Set NextBlock to be the MBB immediately after the current one, if any.
// This is used to avoid emitting unnecessary branches to the next block.
@@ -1521,15 +1488,12 @@ void SelectionDAGBuilder::visitBitTestHeader(BitTestBlock &B) {
MVT::Other, CopyTo, RangeCmp,
DAG.getBasicBlock(B.Default));
- if (DisableScheduling)
- DAG.AssignOrdering(BrRange.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(BrRange.getNode(), SDNodeOrder);
if (MBB != NextBlock) {
BrRange = DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, CopyTo,
DAG.getBasicBlock(MBB));
-
- if (DisableScheduling)
- DAG.AssignOrdering(BrRange.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(BrRange.getNode(), SDNodeOrder);
}
DAG.setRoot(BrRange);
@@ -1556,12 +1520,10 @@ void SelectionDAGBuilder::visitBitTestCase(MachineBasicBlock* NextMBB,
AndOp, DAG.getConstant(0, TLI.getPointerTy()),
ISD::SETNE);
- if (DisableScheduling) {
- DAG.AssignOrdering(ShiftOp.getNode(), SDNodeOrder);
- DAG.AssignOrdering(SwitchVal.getNode(), SDNodeOrder);
- DAG.AssignOrdering(AndOp.getNode(), SDNodeOrder);
- DAG.AssignOrdering(AndCmp.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(ShiftOp.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(SwitchVal.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(AndOp.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(AndCmp.getNode(), SDNodeOrder);
CurMBB->addSuccessor(B.TargetBB);
CurMBB->addSuccessor(NextMBB);
@@ -1570,8 +1532,7 @@ void SelectionDAGBuilder::visitBitTestCase(MachineBasicBlock* NextMBB,
MVT::Other, getControlRoot(),
AndCmp, DAG.getBasicBlock(B.TargetBB));
- if (DisableScheduling)
- DAG.AssignOrdering(BrAnd.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(BrAnd.getNode(), SDNodeOrder);
// Set NextBlock to be the MBB immediately after the current one, if any.
// This is used to avoid emitting unnecessary branches to the next block.
@@ -1583,9 +1544,7 @@ void SelectionDAGBuilder::visitBitTestCase(MachineBasicBlock* NextMBB,
if (NextMBB != NextBlock) {
BrAnd = DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, BrAnd,
DAG.getBasicBlock(NextMBB));
-
- if (DisableScheduling)
- DAG.AssignOrdering(BrAnd.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(BrAnd.getNode(), SDNodeOrder);
}
DAG.setRoot(BrAnd);
@@ -1615,9 +1574,7 @@ void SelectionDAGBuilder::visitInvoke(InvokeInst &I) {
MVT::Other, getControlRoot(),
DAG.getBasicBlock(Return));
DAG.setRoot(Branch);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Branch.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Branch.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitUnwind(UnwindInst &I) {
@@ -2134,9 +2091,7 @@ void SelectionDAGBuilder::visitSwitch(SwitchInst &SI) {
MVT::Other, getControlRoot(),
DAG.getBasicBlock(Default));
DAG.setRoot(Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
return;
@@ -2194,9 +2149,7 @@ void SelectionDAGBuilder::visitIndirectBr(IndirectBrInst &I) {
MVT::Other, getControlRoot(),
getValue(I.getAddress()));
DAG.setRoot(Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitFSub(User &I) {
@@ -2214,10 +2167,7 @@ void SelectionDAGBuilder::visitFSub(User &I) {
SDValue Res = DAG.getNode(ISD::FNEG, getCurDebugLoc(),
Op2.getValueType(), Op2);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
-
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return;
}
}
@@ -2229,10 +2179,7 @@ void SelectionDAGBuilder::visitFSub(User &I) {
SDValue Res = DAG.getNode(ISD::FNEG, getCurDebugLoc(),
Op2.getValueType(), Op2);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
-
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return;
}
@@ -2245,9 +2192,7 @@ void SelectionDAGBuilder::visitBinary(User &I, unsigned OpCode) {
SDValue Res = DAG.getNode(OpCode, getCurDebugLoc(),
Op1.getValueType(), Op1, Op2);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitShift(User &I, unsigned Opcode) {
@@ -2283,12 +2228,9 @@ void SelectionDAGBuilder::visitShift(User &I, unsigned Opcode) {
SDValue Res = DAG.getNode(Opcode, getCurDebugLoc(),
Op1.getValueType(), Op1, Op2);
setValue(&I, Res);
-
- if (DisableScheduling) {
- DAG.AssignOrdering(Op1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Op2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(Op1.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Op2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitICmp(User &I) {
@@ -2304,9 +2246,7 @@ void SelectionDAGBuilder::visitICmp(User &I) {
EVT DestVT = TLI.getValueType(I.getType());
SDValue Res = DAG.getSetCC(getCurDebugLoc(), DestVT, Op1, Op2, Opcode);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitFCmp(User &I) {
@@ -2321,9 +2261,7 @@ void SelectionDAGBuilder::visitFCmp(User &I) {
EVT DestVT = TLI.getValueType(I.getType());
SDValue Res = DAG.getSetCC(getCurDebugLoc(), DestVT, Op1, Op2, Condition);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitSelect(User &I) {
@@ -2345,17 +2283,14 @@ void SelectionDAGBuilder::visitSelect(User &I) {
SDValue(FalseVal.getNode(),
FalseVal.getResNo() + i));
- if (DisableScheduling)
- DAG.AssignOrdering(Values[i].getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Values[i].getNode(), SDNodeOrder);
}
SDValue Res = DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
DAG.getVTList(&ValueVTs[0], NumValues),
&Values[0], NumValues);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitTrunc(User &I) {
@@ -2364,9 +2299,7 @@ void SelectionDAGBuilder::visitTrunc(User &I) {
EVT DestVT = TLI.getValueType(I.getType());
SDValue Res = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), DestVT, N);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitZExt(User &I) {
@@ -2376,9 +2309,7 @@ void SelectionDAGBuilder::visitZExt(User &I) {
EVT DestVT = TLI.getValueType(I.getType());
SDValue Res = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), DestVT, N);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitSExt(User &I) {
@@ -2388,9 +2319,7 @@ void SelectionDAGBuilder::visitSExt(User &I) {
EVT DestVT = TLI.getValueType(I.getType());
SDValue Res = DAG.getNode(ISD::SIGN_EXTEND, getCurDebugLoc(), DestVT, N);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitFPTrunc(User &I) {
@@ -2400,9 +2329,7 @@ void SelectionDAGBuilder::visitFPTrunc(User &I) {
SDValue Res = DAG.getNode(ISD::FP_ROUND, getCurDebugLoc(),
DestVT, N, DAG.getIntPtrConstant(0));
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitFPExt(User &I){
@@ -2411,9 +2338,7 @@ void SelectionDAGBuilder::visitFPExt(User &I){
EVT DestVT = TLI.getValueType(I.getType());
SDValue Res = DAG.getNode(ISD::FP_EXTEND, getCurDebugLoc(), DestVT, N);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitFPToUI(User &I) {
@@ -2422,9 +2347,7 @@ void SelectionDAGBuilder::visitFPToUI(User &I) {
EVT DestVT = TLI.getValueType(I.getType());
SDValue Res = DAG.getNode(ISD::FP_TO_UINT, getCurDebugLoc(), DestVT, N);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitFPToSI(User &I) {
@@ -2433,9 +2356,7 @@ void SelectionDAGBuilder::visitFPToSI(User &I) {
EVT DestVT = TLI.getValueType(I.getType());
SDValue Res = DAG.getNode(ISD::FP_TO_SINT, getCurDebugLoc(), DestVT, N);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitUIToFP(User &I) {
@@ -2444,9 +2365,7 @@ void SelectionDAGBuilder::visitUIToFP(User &I) {
EVT DestVT = TLI.getValueType(I.getType());
SDValue Res = DAG.getNode(ISD::UINT_TO_FP, getCurDebugLoc(), DestVT, N);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitSIToFP(User &I){
@@ -2455,9 +2374,7 @@ void SelectionDAGBuilder::visitSIToFP(User &I){
EVT DestVT = TLI.getValueType(I.getType());
SDValue Res = DAG.getNode(ISD::SINT_TO_FP, getCurDebugLoc(), DestVT, N);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitPtrToInt(User &I) {
@@ -2468,9 +2385,7 @@ void SelectionDAGBuilder::visitPtrToInt(User &I) {
EVT DestVT = TLI.getValueType(I.getType());
SDValue Res = DAG.getZExtOrTrunc(N, getCurDebugLoc(), DestVT);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitIntToPtr(User &I) {
@@ -2481,9 +2396,7 @@ void SelectionDAGBuilder::visitIntToPtr(User &I) {
EVT DestVT = TLI.getValueType(I.getType());
SDValue Res = DAG.getZExtOrTrunc(N, getCurDebugLoc(), DestVT);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitBitCast(User &I) {
@@ -2496,9 +2409,7 @@ void SelectionDAGBuilder::visitBitCast(User &I) {
SDValue Res = DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(),
DestVT, N); // convert types.
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
} else {
setValue(&I, N); // noop cast.
}
@@ -2515,10 +2426,8 @@ void SelectionDAGBuilder::visitInsertElement(User &I) {
InVec, InVal, InIdx);
setValue(&I, Res);
- if (DisableScheduling) {
- DAG.AssignOrdering(InIdx.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(InIdx.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitExtractElement(User &I) {
@@ -2530,10 +2439,8 @@ void SelectionDAGBuilder::visitExtractElement(User &I) {
TLI.getValueType(I.getType()), InVec, InIdx);
setValue(&I, Res);
- if (DisableScheduling) {
- DAG.AssignOrdering(InIdx.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(InIdx.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
@@ -2573,10 +2480,7 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) {
SDValue Res = DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2,
&Mask[0]);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
-
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return;
}
@@ -2590,10 +2494,7 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) {
SDValue Res = DAG.getNode(ISD::CONCAT_VECTORS, getCurDebugLoc(),
VT, Src1, Src2);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
-
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return;
}
@@ -2628,13 +2529,9 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) {
SDValue Res = DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2,
&MappedOps[0]);
setValue(&I, Res);
-
- if (DisableScheduling) {
- DAG.AssignOrdering(Src1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Src2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
- }
-
+ DAG.AssignOrdering(Src1.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Src2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return;
}
@@ -2688,10 +2585,7 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) {
if (RangeUse[0] == 0 && RangeUse[1] == 0) {
SDValue Res = DAG.getUNDEF(VT);
setValue(&I, Res); // Vectors are not used.
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
-
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return;
}
else if (RangeUse[0] < 2 && RangeUse[1] < 2) {
@@ -2704,8 +2598,7 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) {
Src = DAG.getNode(ISD::EXTRACT_SUBVECTOR, getCurDebugLoc(), VT,
Src, DAG.getIntPtrConstant(StartIdx[Input]));
- if (DisableScheduling)
- DAG.AssignOrdering(Src.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Src.getNode(), SDNodeOrder);
}
// Calculate new mask.
@@ -2723,10 +2616,7 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) {
SDValue Res = DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2,
&MappedOps[0]);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
-
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return;
}
}
@@ -2753,18 +2643,14 @@ void SelectionDAGBuilder::visitShuffleVector(User &I) {
DAG.getConstant(Idx - SrcNumElts, PtrVT));
Ops.push_back(Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
}
SDValue Res = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(),
VT, &Ops[0], Ops.size());
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitInsertValue(InsertValueInst &I) {
@@ -2807,9 +2693,7 @@ void SelectionDAGBuilder::visitInsertValue(InsertValueInst &I) {
DAG.getVTList(&AggValueVTs[0], NumAggValues),
&Values[0], NumAggValues);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitExtractValue(ExtractValueInst &I) {
@@ -2839,9 +2723,7 @@ void SelectionDAGBuilder::visitExtractValue(ExtractValueInst &I) {
DAG.getVTList(&ValValueVTs[0], NumValValues),
&Values[0], NumValValues);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitGetElementPtr(User &I) {
@@ -2858,9 +2740,7 @@ void SelectionDAGBuilder::visitGetElementPtr(User &I) {
uint64_t Offset = TD->getStructLayout(StTy)->getElementOffset(Field);
N = DAG.getNode(ISD::ADD, getCurDebugLoc(), N.getValueType(), N,
DAG.getIntPtrConstant(Offset));
-
- if (DisableScheduling)
- DAG.AssignOrdering(N.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(N.getNode(), SDNodeOrder);
}
Ty = StTy->getElementType(Field);
@@ -2885,11 +2765,8 @@ void SelectionDAGBuilder::visitGetElementPtr(User &I) {
N = DAG.getNode(ISD::ADD, getCurDebugLoc(), N.getValueType(), N,
OffsVal);
- if (DisableScheduling) {
- DAG.AssignOrdering(OffsVal.getNode(), SDNodeOrder);
- DAG.AssignOrdering(N.getNode(), SDNodeOrder);
- }
-
+ DAG.AssignOrdering(OffsVal.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(N.getNode(), SDNodeOrder);
continue;
}
@@ -2916,15 +2793,12 @@ void SelectionDAGBuilder::visitGetElementPtr(User &I) {
N.getValueType(), IdxN, Scale);
}
- if (DisableScheduling)
- DAG.AssignOrdering(IdxN.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(IdxN.getNode(), SDNodeOrder);
}
N = DAG.getNode(ISD::ADD, getCurDebugLoc(),
N.getValueType(), N, IdxN);
-
- if (DisableScheduling)
- DAG.AssignOrdering(N.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(N.getNode(), SDNodeOrder);
}
}
@@ -2949,14 +2823,11 @@ void SelectionDAGBuilder::visitAlloca(AllocaInst &I) {
AllocSize,
DAG.getConstant(TySize, AllocSize.getValueType()));
- if (DisableScheduling)
- DAG.AssignOrdering(AllocSize.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(AllocSize.getNode(), SDNodeOrder);
EVT IntPtr = TLI.getPointerTy();
AllocSize = DAG.getZExtOrTrunc(AllocSize, getCurDebugLoc(), IntPtr);
-
- if (DisableScheduling)
- DAG.AssignOrdering(AllocSize.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(AllocSize.getNode(), SDNodeOrder);
// Handle alignment. If the requested alignment is less than or equal to
// the stack alignment, ignore it. If the size is greater than or equal to
@@ -2971,15 +2842,13 @@ void SelectionDAGBuilder::visitAlloca(AllocaInst &I) {
AllocSize = DAG.getNode(ISD::ADD, getCurDebugLoc(),
AllocSize.getValueType(), AllocSize,
DAG.getIntPtrConstant(StackAlign-1));
- if (DisableScheduling)
- DAG.AssignOrdering(AllocSize.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(AllocSize.getNode(), SDNodeOrder);
// Mask out the low bits for alignment purposes.
AllocSize = DAG.getNode(ISD::AND, getCurDebugLoc(),
AllocSize.getValueType(), AllocSize,
DAG.getIntPtrConstant(~(uint64_t)(StackAlign-1)));
- if (DisableScheduling)
- DAG.AssignOrdering(AllocSize.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(AllocSize.getNode(), SDNodeOrder);
SDValue Ops[] = { getRoot(), AllocSize, DAG.getIntPtrConstant(Align) };
SDVTList VTs = DAG.getVTList(AllocSize.getValueType(), MVT::Other);
@@ -2987,9 +2856,7 @@ void SelectionDAGBuilder::visitAlloca(AllocaInst &I) {
VTs, Ops, 3);
setValue(&I, DSA);
DAG.setRoot(DSA.getValue(1));
-
- if (DisableScheduling)
- DAG.AssignOrdering(DSA.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(DSA.getNode(), SDNodeOrder);
// Inform the Frame Information that we have just allocated a variable-sized
// object.
@@ -3038,10 +2905,8 @@ void SelectionDAGBuilder::visitLoad(LoadInst &I) {
Values[i] = L;
Chains[i] = L.getValue(1);
- if (DisableScheduling) {
- DAG.AssignOrdering(A.getNode(), SDNodeOrder);
- DAG.AssignOrdering(L.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(A.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(L.getNode(), SDNodeOrder);
}
if (!ConstantMemory) {
@@ -3052,17 +2917,14 @@ void SelectionDAGBuilder::visitLoad(LoadInst &I) {
else
PendingLoads.push_back(Chain);
- if (DisableScheduling)
- DAG.AssignOrdering(Chain.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Chain.getNode(), SDNodeOrder);
}
SDValue Res = DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
DAG.getVTList(&ValueVTs[0], NumValues),
&Values[0], NumValues);
setValue(&I, Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
void SelectionDAGBuilder::visitStore(StoreInst &I) {
@@ -3095,18 +2957,14 @@ void SelectionDAGBuilder::visitStore(StoreInst &I) {
SDValue(Src.getNode(), Src.getResNo() + i),
Add, PtrV, Offsets[i], isVolatile, Alignment);
- if (DisableScheduling) {
- DAG.AssignOrdering(Add.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Chains[i].getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(Add.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Chains[i].getNode(), SDNodeOrder);
}
SDValue Res = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(),
MVT::Other, &Chains[0], NumValues);
DAG.setRoot(Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
/// visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC
@@ -3177,8 +3035,7 @@ void SelectionDAGBuilder::visitTargetIntrinsic(CallInst &I,
VTs, &Ops[0], Ops.size());
}
- if (DisableScheduling)
- DAG.AssignOrdering(Result.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Result.getNode(), SDNodeOrder);
if (HasChain) {
SDValue Chain = Result.getValue(Result.getNode()->getNumValues()-1);
@@ -3192,9 +3049,7 @@ void SelectionDAGBuilder::visitTargetIntrinsic(CallInst &I,
if (const VectorType *PTy = dyn_cast<VectorType>(I.getType())) {
EVT VT = TLI.getValueType(PTy);
Result = DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(), VT, Result);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Result.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Result.getNode(), SDNodeOrder);
}
setValue(&I, Result);
@@ -3215,12 +3070,9 @@ GetSignificand(SelectionDAG &DAG, SDValue Op, DebugLoc dl, unsigned Order) {
DAG.getConstant(0x3f800000, MVT::i32));
SDValue Res = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t2);
- if (DisableScheduling) {
- DAG.AssignOrdering(t1.getNode(), Order);
- DAG.AssignOrdering(t2.getNode(), Order);
- DAG.AssignOrdering(Res.getNode(), Order);
- }
-
+ DAG.AssignOrdering(t1.getNode(), Order);
+ DAG.AssignOrdering(t2.getNode(), Order);
+ DAG.AssignOrdering(Res.getNode(), Order);
return Res;
}
@@ -3240,13 +3092,10 @@ GetExponent(SelectionDAG &DAG, SDValue Op, const TargetLowering &TLI,
DAG.getConstant(127, MVT::i32));
SDValue Res = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, t2);
- if (DisableScheduling) {
- DAG.AssignOrdering(t0.getNode(), Order);
- DAG.AssignOrdering(t1.getNode(), Order);
- DAG.AssignOrdering(t2.getNode(), Order);
- DAG.AssignOrdering(Res.getNode(), Order);
- }
-
+ DAG.AssignOrdering(t0.getNode(), Order);
+ DAG.AssignOrdering(t1.getNode(), Order);
+ DAG.AssignOrdering(t2.getNode(), Order);
+ DAG.AssignOrdering(Res.getNode(), Order);
return Res;
}
@@ -3271,10 +3120,7 @@ SelectionDAGBuilder::implVisitBinaryAtomic(CallInst& I, ISD::NodeType Op) {
I.getOperand(1));
setValue(&I, L);
DAG.setRoot(L.getValue(1));
-
- if (DisableScheduling)
- DAG.AssignOrdering(L.getNode(), SDNodeOrder);
-
+ DAG.AssignOrdering(L.getNode(), SDNodeOrder);
return 0;
}
@@ -3288,10 +3134,7 @@ SelectionDAGBuilder::implVisitAluOverflow(CallInst &I, ISD::NodeType Op) {
SDValue Result = DAG.getNode(Op, getCurDebugLoc(), VTs, Op1, Op2);
setValue(&I, Result);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Result.getNode(), SDNodeOrder);
-
+ DAG.AssignOrdering(Result.getNode(), SDNodeOrder);
return 0;
}
@@ -3319,19 +3162,15 @@ SelectionDAGBuilder::visitExp(CallInst &I) {
SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, IntegerPartOfX);
SDValue X = DAG.getNode(ISD::FSUB, dl, MVT::f32, t0, t1);
- if (DisableScheduling) {
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(X.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(X.getNode(), SDNodeOrder);
// IntegerPartOfX <<= 23;
IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX,
DAG.getConstant(23, TLI.getPointerTy()));
-
- if (DisableScheduling)
- DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder);
if (LimitFloatPrecision <= 6) {
// For floating-point precision of 6:
@@ -3356,15 +3195,13 @@ SelectionDAGBuilder::visitExp(CallInst &I) {
result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t6);
- if (DisableScheduling) {
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(TwoToFracPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(TwoToFracPartOfX.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
// For floating-point precision of 12:
//
@@ -3392,17 +3229,15 @@ SelectionDAGBuilder::visitExp(CallInst &I) {
result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t8);
- if (DisableScheduling) {
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
- DAG.AssignOrdering(TwoToFracPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(TwoToFracPartOfX.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
// For floating-point precision of 18:
//
@@ -3443,31 +3278,28 @@ SelectionDAGBuilder::visitExp(CallInst &I) {
result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t14);
- if (DisableScheduling) {
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t9.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t10.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t11.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t12.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t13.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t14.getNode(), SDNodeOrder);
- DAG.AssignOrdering(TwoToFracPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t9.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t10.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t11.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t12.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t13.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t14.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(TwoToFracPartOfX.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
} else {
// No special expansion.
result = DAG.getNode(ISD::FEXP, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
- if (DisableScheduling)
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
setValue(&I, result);
@@ -3485,16 +3317,14 @@ SelectionDAGBuilder::visitLog(CallInst &I) {
SDValue Op = getValue(I.getOperand(1));
SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op);
- if (DisableScheduling)
- DAG.AssignOrdering(Op1.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Op1.getNode(), SDNodeOrder);
// Scale the exponent by log(2) [0.69314718f].
SDValue Exp = GetExponent(DAG, Op1, TLI, dl, SDNodeOrder);
SDValue LogOfExponent = DAG.getNode(ISD::FMUL, dl, MVT::f32, Exp,
getF32Constant(DAG, 0x3f317218));
- if (DisableScheduling)
- DAG.AssignOrdering(LogOfExponent.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(LogOfExponent.getNode(), SDNodeOrder);
// Get the significand and build it into a floating-point number with
// exponent of 1.
@@ -3519,13 +3349,11 @@ SelectionDAGBuilder::visitLog(CallInst &I) {
result = DAG.getNode(ISD::FADD, dl,
MVT::f32, LogOfExponent, LogOfMantissa);
- if (DisableScheduling) {
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(LogOfMantissa.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(LogOfMantissa.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
// For floating-point precision of 12:
//
@@ -3553,17 +3381,15 @@ SelectionDAGBuilder::visitLog(CallInst &I) {
result = DAG.getNode(ISD::FADD, dl,
MVT::f32, LogOfExponent, LogOfMantissa);
- if (DisableScheduling) {
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(LogOfMantissa.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(LogOfMantissa.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
// For floating-point precision of 18:
//
@@ -3599,30 +3425,26 @@ SelectionDAGBuilder::visitLog(CallInst &I) {
result = DAG.getNode(ISD::FADD, dl,
MVT::f32, LogOfExponent, LogOfMantissa);
- if (DisableScheduling) {
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t9.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t10.getNode(), SDNodeOrder);
- DAG.AssignOrdering(LogOfMantissa.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t9.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t10.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(LogOfMantissa.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
} else {
// No special expansion.
result = DAG.getNode(ISD::FLOG, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
-
- if (DisableScheduling)
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
setValue(&I, result);
@@ -3640,14 +3462,12 @@ SelectionDAGBuilder::visitLog2(CallInst &I) {
SDValue Op = getValue(I.getOperand(1));
SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op);
- if (DisableScheduling)
- DAG.AssignOrdering(Op1.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Op1.getNode(), SDNodeOrder);
// Get the exponent.
SDValue LogOfExponent = GetExponent(DAG, Op1, TLI, dl, SDNodeOrder);
- if (DisableScheduling)
- DAG.AssignOrdering(LogOfExponent.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(LogOfExponent.getNode(), SDNodeOrder);
// Get the significand and build it into a floating-point number with
// exponent of 1.
@@ -3672,13 +3492,11 @@ SelectionDAGBuilder::visitLog2(CallInst &I) {
result = DAG.getNode(ISD::FADD, dl,
MVT::f32, LogOfExponent, Log2ofMantissa);
- if (DisableScheduling) {
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Log2ofMantissa.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Log2ofMantissa.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
// For floating-point precision of 12:
//
@@ -3706,17 +3524,15 @@ SelectionDAGBuilder::visitLog2(CallInst &I) {
result = DAG.getNode(ISD::FADD, dl,
MVT::f32, LogOfExponent, Log2ofMantissa);
- if (DisableScheduling) {
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Log2ofMantissa.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Log2ofMantissa.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
// For floating-point precision of 18:
//
@@ -3753,30 +3569,26 @@ SelectionDAGBuilder::visitLog2(CallInst &I) {
result = DAG.getNode(ISD::FADD, dl,
MVT::f32, LogOfExponent, Log2ofMantissa);
- if (DisableScheduling) {
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t9.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t10.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Log2ofMantissa.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t9.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t10.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Log2ofMantissa.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
} else {
// No special expansion.
result = DAG.getNode(ISD::FLOG2, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
-
- if (DisableScheduling)
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
setValue(&I, result);
@@ -3794,16 +3606,14 @@ SelectionDAGBuilder::visitLog10(CallInst &I) {
SDValue Op = getValue(I.getOperand(1));
SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op);
- if (DisableScheduling)
- DAG.AssignOrdering(Op1.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Op1.getNode(), SDNodeOrder);
// Scale the exponent by log10(2) [0.30102999f].
SDValue Exp = GetExponent(DAG, Op1, TLI, dl, SDNodeOrder);
SDValue LogOfExponent = DAG.getNode(ISD::FMUL, dl, MVT::f32, Exp,
getF32Constant(DAG, 0x3e9a209a));
- if (DisableScheduling)
- DAG.AssignOrdering(LogOfExponent.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(LogOfExponent.getNode(), SDNodeOrder);
// Get the significand and build it into a floating-point number with
// exponent of 1.
@@ -3828,13 +3638,11 @@ SelectionDAGBuilder::visitLog10(CallInst &I) {
result = DAG.getNode(ISD::FADD, dl,
MVT::f32, LogOfExponent, Log10ofMantissa);
- if (DisableScheduling) {
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Log10ofMantissa.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Log10ofMantissa.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
// For floating-point precision of 12:
//
@@ -3858,15 +3666,13 @@ SelectionDAGBuilder::visitLog10(CallInst &I) {
result = DAG.getNode(ISD::FADD, dl,
MVT::f32, LogOfExponent, Log10ofMantissa);
- if (DisableScheduling) {
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Log10ofMantissa.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Log10ofMantissa.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
// For floating-point precision of 18:
//
@@ -3898,28 +3704,24 @@ SelectionDAGBuilder::visitLog10(CallInst &I) {
result = DAG.getNode(ISD::FADD, dl,
MVT::f32, LogOfExponent, Log10ofMantissa);
- if (DisableScheduling) {
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Log10ofMantissa.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Log10ofMantissa.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
} else {
// No special expansion.
result = DAG.getNode(ISD::FLOG10, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
-
- if (DisableScheduling)
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
setValue(&I, result);
@@ -3938,8 +3740,7 @@ SelectionDAGBuilder::visitExp2(CallInst &I) {
SDValue IntegerPartOfX = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Op);
- if (DisableScheduling)
- DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder);
// FractionalPartOfX = x - (float)IntegerPartOfX;
SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, IntegerPartOfX);
@@ -3949,11 +3750,9 @@ SelectionDAGBuilder::visitExp2(CallInst &I) {
IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX,
DAG.getConstant(23, TLI.getPointerTy()));
- if (DisableScheduling) {
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(X.getNode(), SDNodeOrder);
- DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(X.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder);
if (LimitFloatPrecision <= 6) {
// For floating-point precision of 6:
@@ -3977,15 +3776,13 @@ SelectionDAGBuilder::visitExp2(CallInst &I) {
result = DAG.getNode(ISD::BIT_CONVERT, dl,
MVT::f32, TwoToFractionalPartOfX);
- if (DisableScheduling) {
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
// For floating-point precision of 12:
//
@@ -4012,17 +3809,15 @@ SelectionDAGBuilder::visitExp2(CallInst &I) {
result = DAG.getNode(ISD::BIT_CONVERT, dl,
MVT::f32, TwoToFractionalPartOfX);
- if (DisableScheduling) {
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
- DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
// For floating-point precision of 18:
//
@@ -4060,32 +3855,28 @@ SelectionDAGBuilder::visitExp2(CallInst &I) {
result = DAG.getNode(ISD::BIT_CONVERT, dl,
MVT::f32, TwoToFractionalPartOfX);
- if (DisableScheduling) {
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t9.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t10.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t11.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t12.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t13.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t14.getNode(), SDNodeOrder);
- DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t9.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t10.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t11.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t12.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t13.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t14.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
} else {
// No special expansion.
result = DAG.getNode(ISD::FEXP2, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
-
- if (DisableScheduling)
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
setValue(&I, result);
@@ -4127,19 +3918,16 @@ SelectionDAGBuilder::visitPow(CallInst &I) {
SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, IntegerPartOfX);
SDValue X = DAG.getNode(ISD::FSUB, dl, MVT::f32, t0, t1);
- if (DisableScheduling) {
- DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
- DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(X.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t0.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t1.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(X.getNode(), SDNodeOrder);
// IntegerPartOfX <<= 23;
IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX,
DAG.getConstant(23, TLI.getPointerTy()));
- if (DisableScheduling)
- DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(IntegerPartOfX.getNode(), SDNodeOrder);
if (LimitFloatPrecision <= 6) {
// For floating-point precision of 6:
@@ -4163,15 +3951,13 @@ SelectionDAGBuilder::visitPow(CallInst &I) {
result = DAG.getNode(ISD::BIT_CONVERT, dl,
MVT::f32, TwoToFractionalPartOfX);
- if (DisableScheduling) {
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
// For floating-point precision of 12:
//
@@ -4198,17 +3984,15 @@ SelectionDAGBuilder::visitPow(CallInst &I) {
result = DAG.getNode(ISD::BIT_CONVERT, dl,
MVT::f32, TwoToFractionalPartOfX);
- if (DisableScheduling) {
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
- DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
} else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
// For floating-point precision of 18:
//
@@ -4246,23 +4030,21 @@ SelectionDAGBuilder::visitPow(CallInst &I) {
result = DAG.getNode(ISD::BIT_CONVERT, dl,
MVT::f32, TwoToFractionalPartOfX);
- if (DisableScheduling) {
- DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t9.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t10.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t11.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t12.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t13.getNode(), SDNodeOrder);
- DAG.AssignOrdering(t14.getNode(), SDNodeOrder);
- DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder);
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(t2.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t3.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t4.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t5.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t6.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t7.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t8.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t9.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t10.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t11.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t12.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t13.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(t14.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(TwoToFractionalPartOfX.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
} else {
// No special expansion.
@@ -4270,9 +4052,7 @@ SelectionDAGBuilder::visitPow(CallInst &I) {
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)),
getValue(I.getOperand(2)));
-
- if (DisableScheduling)
- DAG.AssignOrdering(result.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(result.getNode(), SDNodeOrder);
}
setValue(&I, result);
@@ -4352,15 +4132,13 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
Res = DAG.getNode(ISD::RETURNADDR, dl, TLI.getPointerTy(),
getValue(I.getOperand(1)));
setValue(&I, Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
case Intrinsic::frameaddress:
Res = DAG.getNode(ISD::FRAMEADDR, dl, TLI.getPointerTy(),
getValue(I.getOperand(1)));
setValue(&I, Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
case Intrinsic::setjmp:
return "_setjmp"+!TLI.usesUnderscoreSetJmp();
@@ -4374,8 +4152,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
Res = DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, false,
I.getOperand(1), 0, I.getOperand(2), 0);
DAG.setRoot(Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::memset: {
@@ -4386,8 +4163,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
Res = DAG.getMemset(getRoot(), dl, Op1, Op2, Op3, Align,
I.getOperand(1), 0);
DAG.setRoot(Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::memmove: {
@@ -4406,16 +4182,14 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
Res = DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, false,
I.getOperand(1), 0, I.getOperand(2), 0);
DAG.setRoot(Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
Res = DAG.getMemmove(getRoot(), dl, Op1, Op2, Op3, Align,
I.getOperand(1), 0, I.getOperand(2), 0);
DAG.setRoot(Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::dbg_declare: {
@@ -4457,8 +4231,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
SDValue Op = DAG.getNode(ISD::EXCEPTIONADDR, dl, VTs, Ops, 1);
setValue(&I, Op);
DAG.setRoot(Op.getValue(1));
- if (DisableScheduling)
- DAG.AssignOrdering(Op.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Op.getNode(), SDNodeOrder);
return 0;
}
@@ -4487,10 +4260,8 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
Res = DAG.getSExtOrTrunc(Op, dl, MVT::i32);
setValue(&I, Res);
- if (DisableScheduling) {
- DAG.AssignOrdering(Op.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(Op.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
@@ -4508,8 +4279,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
}
setValue(&I, Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
@@ -4523,8 +4293,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
getValue(I.getOperand(1)),
getValue(I.getOperand(2)));
DAG.setRoot(Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
} else {
setValue(&I, DAG.getConstant(0, TLI.getPointerTy()));
}
@@ -4550,12 +4319,10 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
Res = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(),
FA, Offset);
setValue(&I, Res);
- if (DisableScheduling) {
- DAG.AssignOrdering(CfaArg.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Offset.getNode(), SDNodeOrder);
- DAG.AssignOrdering(FA.getNode(), SDNodeOrder);
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(CfaArg.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Offset.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(FA.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::convertff:
@@ -4588,8 +4355,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
getValue(I.getOperand(3)),
Code);
setValue(&I, Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::sqrt:
@@ -4597,31 +4363,27 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
setValue(&I, Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
case Intrinsic::powi:
Res = ExpandPowI(dl, getValue(I.getOperand(1)), getValue(I.getOperand(2)),
DAG);
setValue(&I, Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
case Intrinsic::sin:
Res = DAG.getNode(ISD::FSIN, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
setValue(&I, Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
case Intrinsic::cos:
Res = DAG.getNode(ISD::FCOS, dl,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
setValue(&I, Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
case Intrinsic::log:
visitLog(I);
@@ -4645,8 +4407,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
SDValue Tmp = getValue(I.getOperand(1));
Res = DAG.getNode(ISD::PCMARKER, dl, MVT::Other, getRoot(), Tmp);
DAG.setRoot(Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::readcyclecounter: {
@@ -4656,8 +4417,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
&Op, 1);
setValue(&I, Res);
DAG.setRoot(Res.getValue(1));
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::bswap:
@@ -4665,16 +4425,14 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1)));
setValue(&I, Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
case Intrinsic::cttz: {
SDValue Arg = getValue(I.getOperand(1));
EVT Ty = Arg.getValueType();
Res = DAG.getNode(ISD::CTTZ, dl, Ty, Arg);
setValue(&I, Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::ctlz: {
@@ -4682,8 +4440,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
EVT Ty = Arg.getValueType();
Res = DAG.getNode(ISD::CTLZ, dl, Ty, Arg);
setValue(&I, Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::ctpop: {
@@ -4691,8 +4448,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
EVT Ty = Arg.getValueType();
Res = DAG.getNode(ISD::CTPOP, dl, Ty, Arg);
setValue(&I, Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::stacksave: {
@@ -4701,16 +4457,14 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
DAG.getVTList(TLI.getPointerTy(), MVT::Other), &Op, 1);
setValue(&I, Res);
DAG.setRoot(Res.getValue(1));
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::stackrestore: {
Res = getValue(I.getOperand(1));
Res = DAG.getNode(ISD::STACKRESTORE, dl, MVT::Other, getRoot(), Res);
DAG.setRoot(Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::stackprotector: {
@@ -4733,8 +4487,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
0, true);
setValue(&I, Res);
DAG.setRoot(Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::objectsize: {
@@ -4752,8 +4505,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
Res = DAG.getConstant(0, Ty);
setValue(&I, Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::var_annotation:
@@ -4777,8 +4529,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
setValue(&I, Res);
DAG.setRoot(Res.getValue(1));
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::gcroot:
@@ -4797,14 +4548,12 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
case Intrinsic::flt_rounds:
Res = DAG.getNode(ISD::FLT_ROUNDS_, dl, MVT::i32);
setValue(&I, Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
case Intrinsic::trap:
Res = DAG.getNode(ISD::TRAP, dl,MVT::Other, getRoot());
DAG.setRoot(Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
case Intrinsic::uadd_with_overflow:
return implVisitAluOverflow(I, ISD::UADDO);
@@ -4827,8 +4576,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
Ops[3] = getValue(I.getOperand(3));
Res = DAG.getNode(ISD::PREFETCH, dl, MVT::Other, &Ops[0], 4);
DAG.setRoot(Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
@@ -4840,8 +4588,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
Res = DAG.getNode(ISD::MEMBARRIER, dl, MVT::Other, &Ops[0], 6);
DAG.setRoot(Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::atomic_cmp_swap: {
@@ -4856,8 +4603,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
I.getOperand(1));
setValue(&I, L);
DAG.setRoot(L.getValue(1));
- if (DisableScheduling)
- DAG.AssignOrdering(L.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(L.getNode(), SDNodeOrder);
return 0;
}
case Intrinsic::atomic_load_add:
@@ -4888,8 +4634,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
// Discard region information.
Res = DAG.getUNDEF(TLI.getPointerTy());
setValue(&I, Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
return 0;
case Intrinsic::invariant_end:
case Intrinsic::lifetime_end:
@@ -5070,8 +4815,7 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
"Null value expected with tail call!");
if (Result.first.getNode()) {
setValue(CS.getInstruction(), Result.first);
- if (DisableScheduling)
- DAG.AssignOrdering(Result.first.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Result.first.getNode(), SDNodeOrder);
} else if (!CanLowerReturn && Result.second.getNode()) {
// The instruction result is the result of loading from the
// hidden sret parameter.
@@ -5098,25 +4842,42 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
SDValue Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(),
MVT::Other, &Chains[0], NumValues);
PendingLoads.push_back(Chain);
+
+ // Collect the legal value parts into potentially illegal values
+ // that correspond to the original function's return values.
+ SmallVector<EVT, 4> RetTys;
+ RetTy = FTy->getReturnType();
+ ComputeValueVTs(TLI, RetTy, RetTys);
+ ISD::NodeType AssertOp = ISD::DELETED_NODE;
+ SmallVector<SDValue, 4> ReturnValues;
+ unsigned CurReg = 0;
+ for (unsigned I = 0, E = RetTys.size(); I != E; ++I) {
+ EVT VT = RetTys[I];
+ EVT RegisterVT = TLI.getRegisterType(RetTy->getContext(), VT);
+ unsigned NumRegs = TLI.getNumRegisters(RetTy->getContext(), VT);
+
+ SDValue ReturnValue =
+ getCopyFromParts(DAG, getCurDebugLoc(), SDNodeOrder, &Values[CurReg], NumRegs,
+ RegisterVT, VT, AssertOp);
+ ReturnValues.push_back(ReturnValue);
+ DAG.AssignOrdering(ReturnValue.getNode(), SDNodeOrder);
+ CurReg += NumRegs;
+ }
+ SDValue Res = DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
+ DAG.getVTList(&RetTys[0], RetTys.size()),
+ &ReturnValues[0], ReturnValues.size());
- SDValue MV = DAG.getNode(ISD::MERGE_VALUES,
- getCurDebugLoc(),
- DAG.getVTList(&OutVTs[0], NumValues),
- &Values[0], NumValues);
- setValue(CS.getInstruction(), MV);
+ setValue(CS.getInstruction(), Res);
- if (DisableScheduling) {
- DAG.AssignOrdering(Chain.getNode(), SDNodeOrder);
- DAG.AssignOrdering(MV.getNode(), SDNodeOrder);
- }
+ DAG.AssignOrdering(Chain.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
}
// As a special case, a null chain means that a tail call has been emitted and
// the DAG root is already updated.
if (Result.second.getNode()) {
DAG.setRoot(Result.second);
- if (DisableScheduling)
- DAG.AssignOrdering(Result.second.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(Result.second.getNode(), SDNodeOrder);
} else {
HasTailCall = true;
}
@@ -5391,9 +5152,7 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl,
}
Chain = P.getValue(1);
-
- if (DisableScheduling)
- DAG.AssignOrdering(P.getNode(), Order);
+ DAG.AssignOrdering(P.getNode(), Order);
// If the source register was virtual and if we know something about it,
// add an assert node.
@@ -5432,9 +5191,7 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl,
if (FromVT != MVT::Other) {
P = DAG.getNode(isSExt ? ISD::AssertSext : ISD::AssertZext, dl,
RegisterVT, P, DAG.getValueType(FromVT));
-
- if (DisableScheduling)
- DAG.AssignOrdering(P.getNode(), Order);
+ DAG.AssignOrdering(P.getNode(), Order);
}
}
}
@@ -5444,8 +5201,7 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl,
Values[Value] = getCopyFromParts(DAG, dl, Order, Parts.begin(),
NumRegs, RegisterVT, ValueVT);
- if (DisableScheduling)
- DAG.AssignOrdering(Values[Value].getNode(), Order);
+ DAG.AssignOrdering(Values[Value].getNode(), Order);
Part += NumRegs;
Parts.clear();
}
@@ -5453,8 +5209,7 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl,
SDValue Res = DAG.getNode(ISD::MERGE_VALUES, dl,
DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
&Values[0], ValueVTs.size());
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), Order);
+ DAG.AssignOrdering(Res.getNode(), Order);
return Res;
}
@@ -5491,9 +5246,7 @@ void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl,
}
Chains[i] = Part.getValue(0);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Part.getNode(), Order);
+ DAG.AssignOrdering(Part.getNode(), Order);
}
if (NumRegs == 1 || Flag)
@@ -5511,8 +5264,7 @@ void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl,
else
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Chains[0], NumRegs);
- if (DisableScheduling)
- DAG.AssignOrdering(Chain.getNode(), Order);
+ DAG.AssignOrdering(Chain.getNode(), Order);
}
/// AddInlineAsmOperands - Add this value to the specified inlineasm node
@@ -5529,8 +5281,7 @@ void RegsForValue::AddInlineAsmOperands(unsigned Code,
SDValue Res = DAG.getTargetConstant(Flag, MVT::i32);
Ops.push_back(Res);
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), Order);
+ DAG.AssignOrdering(Res.getNode(), Order);
for (unsigned Value = 0, Reg = 0, e = ValueVTs.size(); Value != e; ++Value) {
unsigned NumRegs = TLI->getNumRegisters(*DAG.getContext(), ValueVTs[Value]);
@@ -5539,9 +5290,7 @@ void RegsForValue::AddInlineAsmOperands(unsigned Code,
assert(Reg < Regs.size() && "Mismatch in # registers expected");
SDValue Res = DAG.getRegister(Regs[Reg++], RegisterVT);
Ops.push_back(Res);
-
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), Order);
+ DAG.AssignOrdering(Res.getNode(), Order);
}
}
}
@@ -5761,8 +5510,7 @@ GetRegistersForValue(SDISelAsmOperandInfo &OpInfo,
OpInfo.ConstraintVT = RegVT;
}
- if (DisableScheduling)
- DAG.AssignOrdering(OpInfo.CallOperand.getNode(), SDNodeOrder);
+ DAG.AssignOrdering(OpInfo.CallOperand.getNode(), SDNodeOrder);
}
NumRegs = TLI.getNumRegisters(Context, OpInfo.ConstraintVT);
@@ -6483,8 +6231,7 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
"LowerCall emitted a value with the wrong type!");
});
- if (DisableScheduling)
- DAG.AssignOrdering(Chain.getNode(), Order);
+ DAG.AssignOrdering(Chain.getNode(), Order);
// For a tail call, the return value is merely live-out and there aren't
// any nodes in the DAG representing it. Return a special value to
@@ -6513,8 +6260,7 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
getCopyFromParts(DAG, dl, Order, &InVals[CurReg], NumRegs,
RegisterVT, VT, AssertOp);
ReturnValues.push_back(ReturnValue);
- if (DisableScheduling)
- DAG.AssignOrdering(ReturnValue.getNode(), Order);
+ DAG.AssignOrdering(ReturnValue.getNode(), Order);
CurReg += NumRegs;
}
@@ -6527,8 +6273,7 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
SDValue Res = DAG.getNode(ISD::MERGE_VALUES, dl,
DAG.getVTList(&RetTys[0], RetTys.size()),
&ReturnValues[0], ReturnValues.size());
- if (DisableScheduling)
- DAG.AssignOrdering(Res.getNode(), Order);
+ DAG.AssignOrdering(Res.getNode(), Order);
return std::make_pair(Res, Chain);
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 9ac8f83..2bec964 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -144,7 +144,7 @@ namespace llvm {
if (TLI.getSchedulingPreference() == TargetLowering::SchedulingForLatency)
return createTDListDAGScheduler(IS, OptLevel);
assert(TLI.getSchedulingPreference() ==
- TargetLowering::SchedulingForRegPressure && "Unknown sched type!");
+ TargetLowering::SchedulingForRegPressure && "Unknown sched type!");
return createBURRListDAGScheduler(IS, OptLevel);
}
}
@@ -1426,7 +1426,7 @@ void SelectionDAGISel::CannotYetSelect(SDNode *N) {
std::string msg;
raw_string_ostream Msg(msg);
Msg << "Cannot yet select: ";
- N->print(Msg, CurDAG);
+ N->printrFull(Msg, CurDAG);
llvm_report_error(Msg.str());
}
diff --git a/lib/CodeGen/SlotIndexes.cpp b/lib/CodeGen/SlotIndexes.cpp
index b8f529b..a23efb2 100644
--- a/lib/CodeGen/SlotIndexes.cpp
+++ b/lib/CodeGen/SlotIndexes.cpp
@@ -14,6 +14,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Target/TargetInstrInfo.h"
using namespace llvm;
@@ -107,6 +108,8 @@ bool SlotIndexes::runOnMachineFunction(MachineFunction &fn) {
for (MachineBasicBlock::iterator miItr = mbb->begin(), miEnd = mbb->end();
miItr != miEnd; ++miItr) {
MachineInstr *mi = &*miItr;
+ if (mi->getOpcode()==TargetInstrInfo::DEBUG_VALUE)
+ continue;
if (miItr == mbb->getFirstTerminator()) {
push_back(createEntry(0, index));
diff --git a/lib/CodeGen/TailDuplication.cpp b/lib/CodeGen/TailDuplication.cpp
index f51f74d..d6860bc 100644
--- a/lib/CodeGen/TailDuplication.cpp
+++ b/lib/CodeGen/TailDuplication.cpp
@@ -108,12 +108,8 @@ bool TailDuplicatePass::runOnMachineFunction(MachineFunction &MF) {
MMI = getAnalysisIfAvailable<MachineModuleInfo>();
bool MadeChange = false;
- bool MadeChangeThisIteration = true;
- while (MadeChangeThisIteration) {
- MadeChangeThisIteration = false;
- MadeChangeThisIteration |= TailDuplicateBlocks(MF);
- MadeChange |= MadeChangeThisIteration;
- }
+ while (TailDuplicateBlocks(MF))
+ MadeChange = true;
return MadeChange;
}
@@ -437,28 +433,28 @@ bool
TailDuplicatePass::TailDuplicate(MachineBasicBlock *TailBB, MachineFunction &MF,
SmallVector<MachineBasicBlock*, 8> &TDBBs,
SmallVector<MachineInstr*, 16> &Copies) {
- // Pre-regalloc tail duplication hurts compile time and doesn't help
- // much except for indirect branches.
- bool hasIndirectBranch = (!TailBB->empty() &&
- TailBB->back().getDesc().isIndirectBranch());
- if (PreRegAlloc && !hasIndirectBranch)
- return false;
-
// Set the limit on the number of instructions to duplicate, with a default
// of one less than the tail-merge threshold. When optimizing for size,
// duplicate only one, because one branch instruction can be eliminated to
// compensate for the duplication.
unsigned MaxDuplicateCount;
- if (hasIndirectBranch)
+ if (MF.getFunction()->hasFnAttr(Attribute::OptimizeForSize))
+ MaxDuplicateCount = 1;
+ else
+ MaxDuplicateCount = TailDuplicateSize;
+
+ if (PreRegAlloc) {
+ // Pre-regalloc tail duplication hurts compile time and doesn't help
+ // much except for indirect branches.
+ if (TailBB->empty() || !TailBB->back().getDesc().isIndirectBranch())
+ return false;
// If the target has hardware branch prediction that can handle indirect
// branches, duplicating them can often make them predictable when there
// are common paths through the code. The limit needs to be high enough
- // to allow undoing the effects of tail merging.
+ // to allow undoing the effects of tail merging and other optimizations
+ // that rearrange the predecessors of the indirect branch.
MaxDuplicateCount = 20;
- else if (MF.getFunction()->hasFnAttr(Attribute::OptimizeForSize))
- MaxDuplicateCount = 1;
- else
- MaxDuplicateCount = TailDuplicateSize;
+ }
// Don't try to tail-duplicate single-block loops.
if (TailBB->isSuccessor(TailBB))
diff --git a/lib/ExecutionEngine/Interpreter/Makefile b/lib/ExecutionEngine/Interpreter/Makefile
index 5f937c3..4df38ea 100644
--- a/lib/ExecutionEngine/Interpreter/Makefile
+++ b/lib/ExecutionEngine/Interpreter/Makefile
@@ -6,7 +6,9 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMInterpreter
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp
index 0f604ac..4dc119d 100644
--- a/lib/ExecutionEngine/JIT/JITEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp
@@ -20,6 +20,7 @@
#include "llvm/Constants.h"
#include "llvm/Module.h"
#include "llvm/DerivedTypes.h"
+#include "llvm/Analysis/DebugInfo.h"
#include "llvm/CodeGen/JITCodeEmitter.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineConstantPool.h"
@@ -368,12 +369,12 @@ namespace {
// the stub is unused.
DenseMap<void *, SmallPtrSet<const Function*, 1> > StubFnRefs;
- DebugLocTuple PrevDLT;
+ DILocation PrevDLT;
public:
JITEmitter(JIT &jit, JITMemoryManager *JMM, TargetMachine &TM)
: SizeEstimate(0), Resolver(jit, *this), MMI(0), CurFn(0),
- EmittedFunctions(this) {
+ EmittedFunctions(this), PrevDLT(NULL) {
MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager();
if (jit.getJITInfo().needsGOT()) {
MemMgr->AllocateGOT();
@@ -806,10 +807,11 @@ void JITEmitter::AddStubToCurrentFunction(void *StubAddr) {
void JITEmitter::processDebugLoc(DebugLoc DL, bool BeforePrintingInsn) {
if (!DL.isUnknown()) {
- DebugLocTuple CurDLT = EmissionDetails.MF->getDebugLocTuple(DL);
+ DILocation CurDLT = EmissionDetails.MF->getDILocation(DL);
if (BeforePrintingInsn) {
- if (CurDLT.Scope != 0 && PrevDLT != CurDLT) {
+ if (CurDLT.getScope().getNode() != 0
+ && PrevDLT.getNode() != CurDLT.getNode()) {
JITEvent_EmittedFunctionDetails::LineStart NextLine;
NextLine.Address = getCurrentPCValue();
NextLine.Loc = DL;
diff --git a/lib/ExecutionEngine/JIT/Makefile b/lib/ExecutionEngine/JIT/Makefile
index e2c9c61..1c93c06 100644
--- a/lib/ExecutionEngine/JIT/Makefile
+++ b/lib/ExecutionEngine/JIT/Makefile
@@ -6,8 +6,10 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMJIT
+CXXFLAGS = -fno-rtti
# Get the $(ARCH) setting
include $(LEVEL)/Makefile.config
diff --git a/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp b/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp
index d01c4b2..2baf979 100644
--- a/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp
+++ b/lib/ExecutionEngine/JIT/OProfileJITEventListener.cpp
@@ -18,10 +18,12 @@
#define DEBUG_TYPE "oprofile-jit-event-listener"
#include "llvm/Function.h"
+#include "llvm/Metadata.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Errno.h"
#include "llvm/Config/config.h"
@@ -70,15 +72,15 @@ OProfileJITEventListener::~OProfileJITEventListener() {
class FilenameCache {
// Holds the filename of each Scope, so that we can pass a null-terminated
- // string into oprofile.
- DenseMap<MDNode*, std::string> Filenames;
+ // string into oprofile. Use an AssertingVH rather than a ValueMap because we
+ // shouldn't be modifying any MDNodes while this map is alive.
+ DenseMap<AssertingVH<MDNode>, std::string> Filenames;
public:
- const char *getFilename(MDNode *Scope) {
- std::string &Filename = Filenames[Scope];
+ const char *getFilename(DIScope Scope) {
+ std::string &Filename = Filenames[Scope.getNode()];
if (Filename.empty()) {
- DIScope S(Scope);
- Filename = S.getFilename();
+ Filename = Scope.getFilename();
}
return Filename.c_str();
}
@@ -89,9 +91,9 @@ static debug_line_info LineStartToOProfileFormat(
uintptr_t Address, DebugLoc Loc) {
debug_line_info Result;
Result.vma = Address;
- const DebugLocTuple &tuple = MF.getDebugLocTuple(Loc);
- Result.lineno = tuple.Line;
- Result.filename = Filenames.getFilename(tuple.Scope);
+ DILocation DILoc = MF.getDILocation(Loc);
+ Result.lineno = DILoc.getLineNumber();
+ Result.filename = Filenames.getFilename(DILoc.getScope());
DEBUG(dbgs() << "Mapping " << reinterpret_cast<void*>(Result.vma) << " to "
<< Result.filename << ":" << Result.lineno << "\n");
return Result;
diff --git a/lib/ExecutionEngine/Makefile b/lib/ExecutionEngine/Makefile
index e0e050e..2387b0e 100644
--- a/lib/ExecutionEngine/Makefile
+++ b/lib/ExecutionEngine/Makefile
@@ -9,5 +9,6 @@
LEVEL = ../..
LIBRARYNAME = LLVMExecutionEngine
PARALLEL_DIRS = Interpreter JIT
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp
index dcd696c..e2cd47a 100644
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -392,7 +392,7 @@ static Value *RemapOperand(const Value *In,
assert(!isa<GlobalValue>(CPV) && "Unmapped global?");
llvm_unreachable("Unknown type of derived type constant value!");
}
- } else if (isa<MetadataBase>(In)) {
+ } else if (isa<MDNode>(In) || isa<MDString>(In)) {
Result = const_cast<Value*>(In);
} else if (isa<InlineAsm>(In)) {
Result = const_cast<Value*>(In);
diff --git a/lib/Linker/Makefile b/lib/Linker/Makefile
index 19e646b..2179fd2 100644
--- a/lib/Linker/Makefile
+++ b/lib/Linker/Makefile
@@ -10,6 +10,7 @@
LEVEL = ../..
LIBRARYNAME = LLVMLinker
BUILD_ARCHIVE := 1
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/MC/CMakeLists.txt b/lib/MC/CMakeLists.txt
index 8a1a058..9ead33b 100644
--- a/lib/MC/CMakeLists.txt
+++ b/lib/MC/CMakeLists.txt
@@ -2,8 +2,6 @@ add_llvm_library(LLVMMC
MCAsmInfo.cpp
MCAsmInfoCOFF.cpp
MCAsmInfoDarwin.cpp
- MCAsmLexer.cpp
- MCAsmParser.cpp
MCAsmStreamer.cpp
MCAssembler.cpp
MCCodeEmitter.cpp
@@ -20,5 +18,4 @@ add_llvm_library(LLVMMC
MCStreamer.cpp
MCSymbol.cpp
MCValue.cpp
- TargetAsmParser.cpp
)
diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp
index 3e5c97d..547f904 100644
--- a/lib/MC/MCAsmInfo.cpp
+++ b/lib/MC/MCAsmInfo.cpp
@@ -19,8 +19,9 @@
using namespace llvm;
MCAsmInfo::MCAsmInfo() {
- ZeroFillDirective = 0;
- NonexecutableStackDirective = 0;
+ HasSubsectionsViaSymbols = false;
+ HasMachoZeroFillDirective = false;
+ HasStaticCtorDtorReferenceInStaticMode = false;
NeedsSet = false;
MaxInstLength = 4;
PCSymbol = "$";
@@ -36,7 +37,6 @@ MCAsmInfo::MCAsmInfo() {
AllowQuotesInName = false;
AllowNameToStartWithDigit = false;
ZeroDirective = "\t.zero\t";
- ZeroDirectiveSuffix = 0;
AsciiDirective = "\t.ascii\t";
AscizDirective = "\t.asciz\t";
Data8bitsDirective = "\t.byte\t";
@@ -52,17 +52,16 @@ MCAsmInfo::MCAsmInfo() {
PICJumpTableDirective = 0;
GlobalDirective = "\t.globl\t";
SetDirective = 0;
- LCOMMDirective = 0;
- COMMDirective = "\t.comm\t";
+ HasLCOMMDirective = false;
COMMDirectiveTakesAlignment = true;
HasDotTypeDotSizeDirective = true;
HasSingleParameterDotFile = true;
- UsedDirective = 0;
+ HasNoDeadStrip = false;
WeakRefDirective = 0;
WeakDefDirective = 0;
- // FIXME: These are ELFish - move to ELFMAI.
- HiddenDirective = "\t.hidden\t";
- ProtectedDirective = "\t.protected\t";
+ LinkOnceDirective = 0;
+ HiddenVisibilityAttr = MCSA_Hidden;
+ ProtectedVisibilityAttr = MCSA_Protected;
AbsoluteDebugSectionOffsets = false;
AbsoluteEHSectionOffsets = false;
HasLEB128 = false;
diff --git a/lib/MC/MCAsmInfoCOFF.cpp b/lib/MC/MCAsmInfoCOFF.cpp
index 23b0dd7..e395acd 100644
--- a/lib/MC/MCAsmInfoCOFF.cpp
+++ b/lib/MC/MCAsmInfoCOFF.cpp
@@ -18,14 +18,17 @@ using namespace llvm;
MCAsmInfoCOFF::MCAsmInfoCOFF() {
GlobalPrefix = "_";
- LCOMMDirective = "\t.lcomm\t";
+ HasLCOMMDirective = true;
COMMDirectiveTakesAlignment = false;
HasDotTypeDotSizeDirective = false;
HasSingleParameterDotFile = false;
- HiddenDirective = NULL;
PrivateGlobalPrefix = "L"; // Prefix for private global symbols
WeakRefDirective = "\t.weak\t";
+ LinkOnceDirective = "\t.linkonce same_size\n";
SetDirective = "\t.set\t";
+
+ // Doesn't support visibility:
+ HiddenVisibilityAttr = ProtectedVisibilityAttr = MCSA_Invalid;
// Set up DWARF directives
HasLEB128 = true; // Target asm supports leb128 directives (little-endian)
diff --git a/lib/MC/MCAsmInfoDarwin.cpp b/lib/MC/MCAsmInfoDarwin.cpp
index d99120d..9902f50 100644
--- a/lib/MC/MCAsmInfoDarwin.cpp
+++ b/lib/MC/MCAsmInfoDarwin.cpp
@@ -24,6 +24,7 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
NeedsSet = true;
AllowQuotesInName = true;
HasSingleParameterDotFile = false;
+ HasSubsectionsViaSymbols = true;
AlignmentIsInBytes = false;
InlineAsmStart = " InlineAsm Start";
@@ -32,14 +33,20 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
// Directives:
WeakDefDirective = "\t.weak_definition ";
WeakRefDirective = "\t.weak_reference ";
- HiddenDirective = "\t.private_extern ";
- LCOMMDirective = "\t.lcomm\t";
ZeroDirective = "\t.space\t"; // ".space N" emits N zeros.
- ZeroFillDirective = "\t.zerofill\t"; // Uses .zerofill
+ HasMachoZeroFillDirective = true; // Uses .zerofill
+ HasStaticCtorDtorReferenceInStaticMode = true;
SetDirective = "\t.set";
- ProtectedDirective = "\t.globl\t";
+
+ HiddenVisibilityAttr = MCSA_PrivateExtern;
+ // Doesn't support protected visibility.
+ ProtectedVisibilityAttr = MCSA_Global;
+
+
HasDotTypeDotSizeDirective = false;
- UsedDirective = "\t.no_dead_strip\t";
+ HasNoDeadStrip = true;
+ // Note: Even though darwin has the .lcomm directive, it is just a synonym for
+ // zerofill, so we prefer to use .zerofill.
// _foo.eh symbols are currently always exported so that the linker knows
// about them. This is not necessary on 10.6 and later, but it
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index b6ebb1a..bf39239 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCStreamer.h"
-#include "llvm/ADT/SmallString.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
@@ -17,26 +16,68 @@
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/FormattedStream.h"
using namespace llvm;
namespace {
class MCAsmStreamer : public MCStreamer {
- raw_ostream &OS;
+ formatted_raw_ostream &OS;
const MCAsmInfo &MAI;
+ bool IsLittleEndian, IsVerboseAsm;
MCInstPrinter *InstPrinter;
MCCodeEmitter *Emitter;
+
+ SmallString<128> CommentToEmit;
+ raw_svector_ostream CommentStream;
public:
- MCAsmStreamer(MCContext &Context, raw_ostream &_OS, const MCAsmInfo &tai,
- MCInstPrinter *_Printer, MCCodeEmitter *_Emitter)
- : MCStreamer(Context), OS(_OS), MAI(tai), InstPrinter(_Printer),
- Emitter(_Emitter) {}
+ MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
+ const MCAsmInfo &mai,
+ bool isLittleEndian, bool isVerboseAsm, MCInstPrinter *printer,
+ MCCodeEmitter *emitter)
+ : MCStreamer(Context), OS(os), MAI(mai), IsLittleEndian(isLittleEndian),
+ IsVerboseAsm(isVerboseAsm), InstPrinter(printer), Emitter(emitter),
+ CommentStream(CommentToEmit) {}
~MCAsmStreamer() {}
+ bool isLittleEndian() const { return IsLittleEndian; }
+
+
+ inline void EmitEOL() {
+ // If we don't have any comments, just emit a \n.
+ if (!IsVerboseAsm) {
+ OS << '\n';
+ return;
+ }
+ EmitCommentsAndEOL();
+ }
+ void EmitCommentsAndEOL();
+
+ /// AddComment - Add a comment that can be emitted to the generated .s
+ /// file if applicable as a QoI issue to make the output of the compiler
+ /// more readable. This only affects the MCAsmStreamer, and only when
+ /// verbose assembly output is enabled.
+ virtual void AddComment(const Twine &T);
+
+ /// GetCommentOS - Return a raw_ostream that comments can be written to.
+ /// Unlike AddComment, you are required to terminate comments with \n if you
+ /// use this method.
+ virtual raw_ostream &GetCommentOS() {
+ if (!IsVerboseAsm)
+ return nulls(); // Discard comments unless in verbose asm mode.
+ return CommentStream;
+ }
+
+ /// AddBlankLine - Emit a blank line to a .s file to pretty it up.
+ virtual void AddBlankLine() {
+ EmitEOL();
+ }
+
/// @name MCStreamer Interface
/// @{
@@ -44,23 +85,33 @@ public:
virtual void EmitLabel(MCSymbol *Symbol);
- virtual void EmitAssemblerFlag(AssemblerFlag Flag);
+ virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
- virtual void EmitSymbolAttribute(MCSymbol *Symbol, SymbolAttr Attribute);
+ virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
- virtual void EmitCommonSymbol(MCSymbol *Symbol, unsigned Size,
+ virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment);
+ /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
+ ///
+ /// @param Symbol - The common symbol to emit.
+ /// @param Size - The size of the common symbol.
+ virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size);
+
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
unsigned Size = 0, unsigned ByteAlignment = 0);
- virtual void EmitBytes(StringRef Data);
+ virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
- virtual void EmitValue(const MCExpr *Value, unsigned Size);
+ virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace);
+ virtual void EmitIntValue(uint64_t Value, unsigned Size, unsigned AddrSpace);
+
+ virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
+ unsigned AddrSpace);
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
@@ -78,6 +129,50 @@ public:
} // end anonymous namespace.
+/// AddComment - Add a comment that can be emitted to the generated .s
+/// file if applicable as a QoI issue to make the output of the compiler
+/// more readable. This only affects the MCAsmStreamer, and only when
+/// verbose assembly output is enabled.
+void MCAsmStreamer::AddComment(const Twine &T) {
+ if (!IsVerboseAsm) return;
+
+ // Make sure that CommentStream is flushed.
+ CommentStream.flush();
+
+ T.toVector(CommentToEmit);
+ // Each comment goes on its own line.
+ CommentToEmit.push_back('\n');
+
+ // Tell the comment stream that the vector changed underneath it.
+ CommentStream.resync();
+}
+
+void MCAsmStreamer::EmitCommentsAndEOL() {
+ if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
+ OS << '\n';
+ return;
+ }
+
+ CommentStream.flush();
+ StringRef Comments = CommentToEmit.str();
+
+ assert(Comments.back() == '\n' &&
+ "Comment array not newline terminated");
+ do {
+ // Emit a line of comments.
+ OS.PadToColumn(MAI.getCommentColumn());
+ size_t Position = Comments.find('\n');
+ OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n';
+
+ Comments = Comments.substr(Position+1);
+ } while (!Comments.empty());
+
+ CommentToEmit.clear();
+ // Tell the comment stream that the vector changed underneath it.
+ CommentStream.resync();
+}
+
+
static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
assert(Bytes && "Invalid size!");
return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
@@ -101,17 +196,17 @@ void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
assert(CurSection && "Cannot emit before setting section!");
- Symbol->print(OS, &MAI);
- OS << ":\n";
+ OS << *Symbol << ":";
+ EmitEOL();
Symbol->setSection(*CurSection);
}
-void MCAsmStreamer::EmitAssemblerFlag(AssemblerFlag Flag) {
+void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
switch (Flag) {
default: assert(0 && "Invalid flag!");
- case SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
+ case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
}
- OS << '\n';
+ EmitEOL();
}
void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
@@ -119,10 +214,8 @@ void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
assert((Symbol->isUndefined() || Symbol->isAbsolute()) &&
"Cannot define a symbol twice!");
- Symbol->print(OS, &MAI);
- OS << " = ";
- Value->print(OS, &MAI);
- OS << '\n';
+ OS << *Symbol << " = " << *Value;
+ EmitEOL();
// FIXME: Lift context changes into super class.
// FIXME: Set associated section.
@@ -130,41 +223,54 @@ void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
}
void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
- SymbolAttr Attribute) {
+ MCSymbolAttr Attribute) {
switch (Attribute) {
- case Global: OS << ".globl"; break;
- case Hidden: OS << ".hidden"; break;
- case IndirectSymbol: OS << ".indirect_symbol"; break;
- case Internal: OS << ".internal"; break;
- case LazyReference: OS << ".lazy_reference"; break;
- case NoDeadStrip: OS << ".no_dead_strip"; break;
- case PrivateExtern: OS << ".private_extern"; break;
- case Protected: OS << ".protected"; break;
- case Reference: OS << ".reference"; break;
- case Weak: OS << ".weak"; break;
- case WeakDefinition: OS << ".weak_definition"; break;
- case WeakReference: OS << ".weak_reference"; break;
+ case MCSA_Invalid: assert(0 && "Invalid symbol attribute");
+ case MCSA_Global: OS << MAI.getGlobalDirective(); break; // .globl
+ case MCSA_Hidden: OS << ".hidden "; break;
+ case MCSA_IndirectSymbol: OS << ".indirect_symbol "; break;
+ case MCSA_Internal: OS << ".internal "; break;
+ case MCSA_LazyReference: OS << ".lazy_reference "; break;
+ case MCSA_Local: OS << ".local "; break;
+ case MCSA_NoDeadStrip: OS << ".no_dead_strip "; break;
+ case MCSA_PrivateExtern: OS << ".private_extern "; break;
+ case MCSA_Protected: OS << ".protected "; break;
+ case MCSA_Reference: OS << ".reference "; break;
+ case MCSA_Weak: OS << ".weak "; break;
+ case MCSA_WeakDefinition: OS << ".weak_definition "; break;
+ // .weak_reference
+ case MCSA_WeakReference: OS << MAI.getWeakRefDirective(); break;
}
- OS << ' ';
- Symbol->print(OS, &MAI);
- OS << '\n';
+ OS << *Symbol;
+ EmitEOL();
}
void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
- OS << ".desc" << ' ';
- Symbol->print(OS, &MAI);
- OS << ',' << DescValue << '\n';
+ OS << ".desc" << ' ' << *Symbol << ',' << DescValue;
+ EmitEOL();
}
-void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, unsigned Size,
+void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {
- OS << ".comm ";
- Symbol->print(OS, &MAI);
- OS << ',' << Size;
- if (ByteAlignment != 0)
- OS << ',' << Log2_32(ByteAlignment);
- OS << '\n';
+ OS << "\t.comm\t" << *Symbol << ',' << Size;
+ if (ByteAlignment != 0 && MAI.getCOMMDirectiveTakesAlignment()) {
+ if (MAI.getAlignmentIsInBytes())
+ OS << ',' << ByteAlignment;
+ else
+ OS << ',' << Log2_32(ByteAlignment);
+ }
+ EmitEOL();
+}
+
+/// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
+///
+/// @param Symbol - The common symbol to emit.
+/// @param Size - The size of the common symbol.
+void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {
+ assert(MAI.hasLCOMMDirective() && "Doesn't have .lcomm, can't emit it!");
+ OS << "\t.lcomm\t" << *Symbol << ',' << Size;
+ EmitEOL();
}
void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
@@ -177,36 +283,130 @@ void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
OS << MOSection->getSegmentName() << "," << MOSection->getSectionName();
if (Symbol != NULL) {
- OS << ',';
- Symbol->print(OS, &MAI);
- OS << ',' << Size;
+ OS << ',' << *Symbol << ',' << Size;
if (ByteAlignment != 0)
OS << ',' << Log2_32(ByteAlignment);
}
- OS << '\n';
+ EmitEOL();
+}
+
+static inline char toOctal(int X) { return (X&7)+'0'; }
+
+void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
+ assert(CurSection && "Cannot emit contents before setting section!");
+ if (Data.empty()) return;
+
+ if (Data.size() == 1) {
+ OS << MAI.getData8bitsDirective(AddrSpace);
+ OS << (unsigned)(unsigned char)Data[0];
+ EmitEOL();
+ return;
+ }
+
+ // If the data ends with 0 and the target supports .asciz, use it, otherwise
+ // use .ascii
+ if (MAI.getAscizDirective() && Data.back() == 0) {
+ OS << MAI.getAscizDirective();
+ Data = Data.substr(0, Data.size()-1);
+ } else {
+ OS << MAI.getAsciiDirective();
+ }
+
+ OS << " \"";
+ for (unsigned i = 0, e = Data.size(); i != e; ++i) {
+ unsigned char C = Data[i];
+ if (C == '"' || C == '\\') {
+ OS << '\\' << (char)C;
+ continue;
+ }
+
+ if (isprint((unsigned char)C)) {
+ OS << (char)C;
+ continue;
+ }
+
+ switch (C) {
+ case '\b': OS << "\\b"; break;
+ case '\f': OS << "\\f"; break;
+ case '\n': OS << "\\n"; break;
+ case '\r': OS << "\\r"; break;
+ case '\t': OS << "\\t"; break;
+ default:
+ OS << '\\';
+ OS << toOctal(C >> 6);
+ OS << toOctal(C >> 3);
+ OS << toOctal(C >> 0);
+ break;
+ }
+ }
+ OS << '"';
+ EmitEOL();
}
-void MCAsmStreamer::EmitBytes(StringRef Data) {
+/// EmitIntValue - Special case of EmitValue that avoids the client having
+/// to pass in a MCExpr for constant integers.
+void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
+ unsigned AddrSpace) {
assert(CurSection && "Cannot emit contents before setting section!");
- for (unsigned i = 0, e = Data.size(); i != e; ++i)
- OS << ".byte " << (unsigned) (unsigned char) Data[i] << '\n';
+ const char *Directive = 0;
+ switch (Size) {
+ default: break;
+ case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
+ case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
+ case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
+ case 8:
+ Directive = MAI.getData64bitsDirective(AddrSpace);
+ // If the target doesn't support 64-bit data, emit as two 32-bit halves.
+ if (Directive) break;
+ if (isLittleEndian()) {
+ EmitIntValue((uint32_t)(Value >> 0 ), 4, AddrSpace);
+ EmitIntValue((uint32_t)(Value >> 32), 4, AddrSpace);
+ } else {
+ EmitIntValue((uint32_t)(Value >> 32), 4, AddrSpace);
+ EmitIntValue((uint32_t)(Value >> 0 ), 4, AddrSpace);
+ }
+ return;
+ }
+
+ assert(Directive && "Invalid size for machine code value!");
+ OS << Directive << truncateToSize(Value, Size);
+ EmitEOL();
}
-void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size) {
+void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size,
+ unsigned AddrSpace) {
assert(CurSection && "Cannot emit contents before setting section!");
- // Need target hooks to know how to print this.
+ const char *Directive = 0;
switch (Size) {
- default:
- llvm_unreachable("Invalid size for machine code value!");
- case 1: OS << ".byte"; break;
- case 2: OS << ".short"; break;
- case 4: OS << ".long"; break;
- case 8: OS << ".quad"; break;
+ default: break;
+ case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
+ case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
+ case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
+ case 8: Directive = MAI.getData64bitsDirective(AddrSpace); break;
}
+
+ assert(Directive && "Invalid size for machine code value!");
+ OS << Directive << *truncateToSize(Value, Size);
+ EmitEOL();
+}
+
+/// EmitFill - Emit NumBytes bytes worth of the value specified by
+/// FillValue. This implements directives such as '.space'.
+void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
+ unsigned AddrSpace) {
+ if (NumBytes == 0) return;
+
+ if (AddrSpace == 0)
+ if (const char *ZeroDirective = MAI.getZeroDirective()) {
+ OS << ZeroDirective << NumBytes;
+ if (FillValue != 0)
+ OS << ',' << (int)FillValue;
+ EmitEOL();
+ return;
+ }
- OS << ' ';
- truncateToSize(Value, Size)->print(OS, &MAI);
- OS << '\n';
+ // Emit a byte at a time.
+ MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace);
}
void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
@@ -236,7 +436,7 @@ void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
if (MaxBytesToEmit)
OS << ", " << MaxBytesToEmit;
}
- OS << '\n';
+ EmitEOL();
return;
}
@@ -254,15 +454,14 @@ void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
OS << ", " << truncateToSize(Value, ValueSize);
if (MaxBytesToEmit)
OS << ", " << MaxBytesToEmit;
- OS << '\n';
+ EmitEOL();
}
void MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
unsigned char Value) {
// FIXME: Verify that Offset is associated with the current section.
- OS << ".org ";
- Offset->print(OS, &MAI);
- OS << ", " << (unsigned) Value << '\n';
+ OS << ".org " << *Offset << ", " << (unsigned) Value;
+ EmitEOL();
}
void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
@@ -271,7 +470,7 @@ void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
// If we have an AsmPrinter, use that to print.
if (InstPrinter) {
InstPrinter->printInst(&Inst);
- OS << '\n';
+ EmitEOL();
// Show the encoding if we have a code emitter.
if (Emitter) {
@@ -296,15 +495,18 @@ void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
// Otherwise fall back to a structural printing for now. Eventually we should
// always have access to the target specific printer.
Inst.print(OS, &MAI);
- OS << '\n';
+ EmitEOL();
}
void MCAsmStreamer::Finish() {
OS.flush();
}
-MCStreamer *llvm::createAsmStreamer(MCContext &Context, raw_ostream &OS,
- const MCAsmInfo &MAI, MCInstPrinter *IP,
+MCStreamer *llvm::createAsmStreamer(MCContext &Context,
+ formatted_raw_ostream &OS,
+ const MCAsmInfo &MAI, bool isLittleEndian,
+ bool isVerboseAsm, MCInstPrinter *IP,
MCCodeEmitter *CE) {
- return new MCAsmStreamer(Context, OS, MAI, IP, CE);
+ return new MCAsmStreamer(Context, OS, MAI, isLittleEndian, isVerboseAsm,
+ IP, CE);
}
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index 1f5b6f1..f0f5a47 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -679,8 +679,6 @@ public:
UndefinedSymbolData[i].SymbolData->setIndex(Index++);
// The string table is padded to a multiple of 4.
- //
- // FIXME: Check to see if this varies per arch.
while (StringTable.size() % 4)
StringTable += '\x00';
}
diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp
index a19ec19..1ee1b1b 100644
--- a/lib/MC/MCExpr.cpp
+++ b/lib/MC/MCExpr.cpp
@@ -15,7 +15,7 @@
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
+void MCExpr::print(raw_ostream &OS) const {
switch (getKind()) {
case MCExpr::Constant:
OS << cast<MCConstantExpr>(*this).getValue();
@@ -26,13 +26,10 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
// Parenthesize names that start with $ so that they don't look like
// absolute names.
- if (Sym.getName()[0] == '$') {
- OS << '(';
- Sym.print(OS, MAI);
- OS << ')';
- } else {
- Sym.print(OS, MAI);
- }
+ if (Sym.getName()[0] == '$')
+ OS << '(' << Sym << ')';
+ else
+ OS << Sym;
return;
}
@@ -45,7 +42,7 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
case MCUnaryExpr::Not: OS << '~'; break;
case MCUnaryExpr::Plus: OS << '+'; break;
}
- UE.getSubExpr()->print(OS, MAI);
+ OS << *UE.getSubExpr();
return;
}
@@ -54,11 +51,9 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
// Only print parens around the LHS if it is non-trivial.
if (isa<MCConstantExpr>(BE.getLHS()) || isa<MCSymbolRefExpr>(BE.getLHS())) {
- BE.getLHS()->print(OS, MAI);
+ OS << *BE.getLHS();
} else {
- OS << '(';
- BE.getLHS()->print(OS, MAI);
- OS << ')';
+ OS << '(' << *BE.getLHS() << ')';
}
switch (BE.getOpcode()) {
@@ -95,11 +90,9 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
// Only print parens around the LHS if it is non-trivial.
if (isa<MCConstantExpr>(BE.getRHS()) || isa<MCSymbolRefExpr>(BE.getRHS())) {
- BE.getRHS()->print(OS, MAI);
+ OS << *BE.getRHS();
} else {
- OS << '(';
- BE.getRHS()->print(OS, MAI);
- OS << ')';
+ OS << '(' << *BE.getRHS() << ')';
}
return;
}
@@ -109,7 +102,7 @@ void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
}
void MCExpr::dump() const {
- print(dbgs(), 0);
+ print(dbgs());
dbgs() << '\n';
}
diff --git a/lib/MC/MCInst.cpp b/lib/MC/MCInst.cpp
index 7c7a644..0634c9f 100644
--- a/lib/MC/MCInst.cpp
+++ b/lib/MC/MCInst.cpp
@@ -23,9 +23,7 @@ void MCOperand::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
else if (isImm())
OS << "Imm:" << getImm();
else if (isExpr()) {
- OS << "Expr:(";
- getExpr()->print(OS, MAI);
- OS << ")";
+ OS << "Expr:(" << *getExpr() << ")";
} else
OS << "UNDEFINED";
OS << ">";
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index 828b92a..e559c65 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -117,36 +117,26 @@ public:
/// @{
virtual void SwitchSection(const MCSection *Section);
-
virtual void EmitLabel(MCSymbol *Symbol);
-
- virtual void EmitAssemblerFlag(AssemblerFlag Flag);
-
+ virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
-
- virtual void EmitSymbolAttribute(MCSymbol *Symbol, SymbolAttr Attribute);
-
+ virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
-
- virtual void EmitCommonSymbol(MCSymbol *Symbol, unsigned Size,
+ virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment);
-
+ virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {
+ assert(0 && "macho doesn't support this directive");
+ }
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
unsigned Size = 0, unsigned ByteAlignment = 0);
-
- virtual void EmitBytes(StringRef Data);
-
- virtual void EmitValue(const MCExpr *Value, unsigned Size);
-
+ virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
+ virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace);
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
unsigned MaxBytesToEmit = 0);
-
virtual void EmitValueToOffset(const MCExpr *Offset,
unsigned char Value = 0);
-
virtual void EmitInstruction(const MCInst &Inst);
-
virtual void Finish();
/// @}
@@ -183,9 +173,9 @@ void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
Symbol->setSection(*CurSection);
}
-void MCMachOStreamer::EmitAssemblerFlag(AssemblerFlag Flag) {
+void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
switch (Flag) {
- case SubsectionsViaSymbols:
+ case MCAF_SubsectionsViaSymbols:
Assembler.setSubsectionsViaSymbols(true);
return;
}
@@ -204,10 +194,10 @@ void MCMachOStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
}
void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
- SymbolAttr Attribute) {
+ MCSymbolAttr Attribute) {
// Indirect symbols are handled differently, to match how 'as' handles
// them. This makes writing matching .o files easier.
- if (Attribute == MCStreamer::IndirectSymbol) {
+ if (Attribute == MCSA_IndirectSymbol) {
// Note that we intentionally cannot use the symbol data here; this is
// important for matching the string table that 'as' generates.
IndirectSymbolData ISD;
@@ -229,19 +219,21 @@ void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
// In the future it might be worth trying to make these operations more well
// defined.
switch (Attribute) {
- case MCStreamer::IndirectSymbol:
- case MCStreamer::Hidden:
- case MCStreamer::Internal:
- case MCStreamer::Protected:
- case MCStreamer::Weak:
+ case MCSA_Invalid:
+ case MCSA_IndirectSymbol:
+ case MCSA_Hidden:
+ case MCSA_Internal:
+ case MCSA_Protected:
+ case MCSA_Weak:
+ case MCSA_Local:
assert(0 && "Invalid symbol attribute for Mach-O!");
break;
- case MCStreamer::Global:
+ case MCSA_Global:
SD.setExternal(true);
break;
- case MCStreamer::LazyReference:
+ case MCSA_LazyReference:
// FIXME: This requires -dynamic.
SD.setFlags(SD.getFlags() | SF_NoDeadStrip);
if (Symbol->isUndefined())
@@ -250,23 +242,23 @@ void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
// Since .reference sets the no dead strip bit, it is equivalent to
// .no_dead_strip in practice.
- case MCStreamer::Reference:
- case MCStreamer::NoDeadStrip:
+ case MCSA_Reference:
+ case MCSA_NoDeadStrip:
SD.setFlags(SD.getFlags() | SF_NoDeadStrip);
break;
- case MCStreamer::PrivateExtern:
+ case MCSA_PrivateExtern:
SD.setExternal(true);
SD.setPrivateExtern(true);
break;
- case MCStreamer::WeakReference:
+ case MCSA_WeakReference:
// FIXME: This requires -dynamic.
if (Symbol->isUndefined())
SD.setFlags(SD.getFlags() | SF_WeakReference);
break;
- case MCStreamer::WeakDefinition:
+ case MCSA_WeakDefinition:
// FIXME: 'as' enforces that this is defined and global. The manual claims
// it has to be in a coalesced section, but this isn't enforced.
SD.setFlags(SD.getFlags() | SF_WeakDefinition);
@@ -281,7 +273,7 @@ void MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
getSymbolData(*Symbol).setFlags(DescValue & SF_DescFlagsMask);
}
-void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, unsigned Size,
+void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {
// FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
@@ -315,14 +307,15 @@ void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
SectData.setAlignment(ByteAlignment);
}
-void MCMachOStreamer::EmitBytes(StringRef Data) {
+void MCMachOStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
MCDataFragment *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
if (!DF)
DF = new MCDataFragment(CurSectionData);
DF->getContents().append(Data.begin(), Data.end());
}
-void MCMachOStreamer::EmitValue(const MCExpr *Value, unsigned Size) {
+void MCMachOStreamer::EmitValue(const MCExpr *Value, unsigned Size,
+ unsigned AddrSpace) {
new MCFillFragment(*AddValueSymbols(Value), Size, 1, CurSectionData);
}
@@ -353,11 +346,13 @@ void MCMachOStreamer::EmitInstruction(const MCInst &Inst) {
if (!Emitter)
llvm_unreachable("no code emitter available!");
+ // FIXME: Emitting an instruction should cause S_ATTR_SOME_INSTRUCTIONS to
+ // be set for the current section.
// FIXME: Relocations!
SmallString<256> Code;
raw_svector_ostream VecOS(Code);
Emitter->EncodeInstruction(Inst, VecOS);
- EmitBytes(VecOS.str());
+ EmitBytes(VecOS.str(), 0);
}
void MCMachOStreamer::Finish() {
diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp
index ddc4e69..7c219b3 100644
--- a/lib/MC/MCNullStreamer.cpp
+++ b/lib/MC/MCNullStreamer.cpp
@@ -31,23 +31,25 @@ namespace {
virtual void EmitLabel(MCSymbol *Symbol) {}
- virtual void EmitAssemblerFlag(AssemblerFlag Flag) {}
+ virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {}
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
- virtual void EmitSymbolAttribute(MCSymbol *Symbol, SymbolAttr Attribute) {}
+ virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute){}
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
- virtual void EmitCommonSymbol(MCSymbol *Symbol, unsigned Size,
+ virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {}
+ virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {}
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
unsigned Size = 0, unsigned ByteAlignment = 0) {}
- virtual void EmitBytes(StringRef Data) {}
+ virtual void EmitBytes(StringRef Data, unsigned AddrSpace) {}
- virtual void EmitValue(const MCExpr *Value, unsigned Size) {}
+ virtual void EmitValue(const MCExpr *Value, unsigned Size,
+ unsigned AddrSpace) {}
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp
new file mode 100644
index 0000000..482eefd
--- /dev/null
+++ b/lib/MC/MCParser/AsmLexer.cpp
@@ -0,0 +1,320 @@
+//===- AsmLexer.cpp - Lexer for Assembly Files ----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class implements the lexer for assembly files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCParser/AsmLexer.h"
+#include "llvm/Support/SMLoc.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include <cerrno>
+#include <cstdio>
+#include <cstdlib>
+using namespace llvm;
+
+AsmLexer::AsmLexer(const MCAsmInfo &_MAI) : MAI(_MAI) {
+ CurBuf = NULL;
+ CurPtr = NULL;
+ TokStart = 0;
+}
+
+AsmLexer::~AsmLexer() {
+}
+
+void AsmLexer::setBuffer(const MemoryBuffer *buf, const char *ptr) {
+ CurBuf = buf;
+
+ if (ptr)
+ CurPtr = ptr;
+ else
+ CurPtr = CurBuf->getBufferStart();
+
+ TokStart = 0;
+}
+
+SMLoc AsmLexer::getLoc() const {
+ return SMLoc::getFromPointer(TokStart);
+}
+
+/// ReturnError - Set the error to the specified string at the specified
+/// location. This is defined to always return AsmToken::Error.
+AsmToken AsmLexer::ReturnError(const char *Loc, const std::string &Msg) {
+ SetError(SMLoc::getFromPointer(Loc), Msg);
+
+ return AsmToken(AsmToken::Error, StringRef(Loc, 0));
+}
+
+int AsmLexer::getNextChar() {
+ char CurChar = *CurPtr++;
+ switch (CurChar) {
+ default:
+ return (unsigned char)CurChar;
+ case 0:
+ // A nul character in the stream is either the end of the current buffer or
+ // a random nul in the file. Disambiguate that here.
+ if (CurPtr-1 != CurBuf->getBufferEnd())
+ return 0; // Just whitespace.
+
+ // Otherwise, return end of file.
+ --CurPtr; // Another call to lex will return EOF again.
+ return EOF;
+ }
+}
+
+/// LexIdentifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
+AsmToken AsmLexer::LexIdentifier() {
+ while (isalnum(*CurPtr) || *CurPtr == '_' || *CurPtr == '$' ||
+ *CurPtr == '.' || *CurPtr == '@')
+ ++CurPtr;
+ return AsmToken(AsmToken::Identifier, StringRef(TokStart, CurPtr - TokStart));
+}
+
+/// LexSlash: Slash: /
+/// C-Style Comment: /* ... */
+AsmToken AsmLexer::LexSlash() {
+ switch (*CurPtr) {
+ case '*': break; // C style comment.
+ case '/': return ++CurPtr, LexLineComment();
+ default: return AsmToken(AsmToken::Slash, StringRef(CurPtr, 1));
+ }
+
+ // C Style comment.
+ ++CurPtr; // skip the star.
+ while (1) {
+ int CurChar = getNextChar();
+ switch (CurChar) {
+ case EOF:
+ return ReturnError(TokStart, "unterminated comment");
+ case '*':
+ // End of the comment?
+ if (CurPtr[0] != '/') break;
+
+ ++CurPtr; // End the */.
+ return LexToken();
+ }
+ }
+}
+
+/// LexLineComment: Comment: #[^\n]*
+/// : //[^\n]*
+AsmToken AsmLexer::LexLineComment() {
+ // FIXME: This is broken if we happen to a comment at the end of a file, which
+ // was .included, and which doesn't end with a newline.
+ int CurChar = getNextChar();
+ while (CurChar != '\n' && CurChar != '\n' && CurChar != EOF)
+ CurChar = getNextChar();
+
+ if (CurChar == EOF)
+ return AsmToken(AsmToken::Eof, StringRef(CurPtr, 0));
+ return AsmToken(AsmToken::EndOfStatement, StringRef(CurPtr, 0));
+}
+
+
+/// LexDigit: First character is [0-9].
+/// Local Label: [0-9][:]
+/// Forward/Backward Label: [0-9][fb]
+/// Binary integer: 0b[01]+
+/// Octal integer: 0[0-7]+
+/// Hex integer: 0x[0-9a-fA-F]+
+/// Decimal integer: [1-9][0-9]*
+/// TODO: FP literal.
+AsmToken AsmLexer::LexDigit() {
+ if (*CurPtr == ':')
+ return ReturnError(TokStart, "FIXME: local label not implemented");
+ if (*CurPtr == 'f' || *CurPtr == 'b')
+ return ReturnError(TokStart, "FIXME: directional label not implemented");
+
+ // Decimal integer: [1-9][0-9]*
+ if (CurPtr[-1] != '0') {
+ while (isdigit(*CurPtr))
+ ++CurPtr;
+
+ StringRef Result(TokStart, CurPtr - TokStart);
+
+ long long Value;
+ if (Result.getAsInteger(10, Value))
+ return ReturnError(TokStart, "Invalid decimal number");
+ return AsmToken(AsmToken::Integer, Result, Value);
+ }
+
+ if (*CurPtr == 'b') {
+ ++CurPtr;
+ const char *NumStart = CurPtr;
+ while (CurPtr[0] == '0' || CurPtr[0] == '1')
+ ++CurPtr;
+
+ // Requires at least one binary digit.
+ if (CurPtr == NumStart)
+ return ReturnError(TokStart, "Invalid binary number");
+
+ StringRef Result(TokStart, CurPtr - TokStart);
+
+ long long Value;
+ if (Result.getAsInteger(2, Value))
+ return ReturnError(TokStart, "Invalid binary number");
+
+ return AsmToken(AsmToken::Integer, Result, Value);
+ }
+
+ if (*CurPtr == 'x') {
+ ++CurPtr;
+ const char *NumStart = CurPtr;
+ while (isxdigit(CurPtr[0]))
+ ++CurPtr;
+
+ // Requires at least one hex digit.
+ if (CurPtr == NumStart)
+ return ReturnError(CurPtr-2, "Invalid hexadecimal number");
+
+ unsigned long long Result;
+ if (StringRef(TokStart, CurPtr - TokStart).getAsInteger(0, Result))
+ return ReturnError(TokStart, "Invalid hexadecimal number");
+
+ return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart),
+ (int64_t)Result);
+ }
+
+ // Must be an octal number, it starts with 0.
+ while (*CurPtr >= '0' && *CurPtr <= '7')
+ ++CurPtr;
+
+ StringRef Result(TokStart, CurPtr - TokStart);
+ long long Value;
+ if (Result.getAsInteger(8, Value))
+ return ReturnError(TokStart, "Invalid octal number");
+
+ return AsmToken(AsmToken::Integer, Result, Value);
+}
+
+/// LexQuote: String: "..."
+AsmToken AsmLexer::LexQuote() {
+ int CurChar = getNextChar();
+ // TODO: does gas allow multiline string constants?
+ while (CurChar != '"') {
+ if (CurChar == '\\') {
+ // Allow \", etc.
+ CurChar = getNextChar();
+ }
+
+ if (CurChar == EOF)
+ return ReturnError(TokStart, "unterminated string constant");
+
+ CurChar = getNextChar();
+ }
+
+ return AsmToken(AsmToken::String, StringRef(TokStart, CurPtr - TokStart));
+}
+
+StringRef AsmLexer::LexUntilEndOfStatement() {
+ TokStart = CurPtr;
+
+ while (!isAtStartOfComment(*CurPtr) && // Start of line comment.
+ *CurPtr != ';' && // End of statement marker.
+ *CurPtr != '\n' &&
+ *CurPtr != '\r' &&
+ (*CurPtr != 0 || CurPtr != CurBuf->getBufferEnd())) {
+ ++CurPtr;
+ }
+ return StringRef(TokStart, CurPtr-TokStart);
+}
+
+bool AsmLexer::isAtStartOfComment(char Char) {
+ // FIXME: This won't work for multi-character comment indicators like "//".
+ return Char == *MAI.getCommentString();
+}
+
+AsmToken AsmLexer::LexToken() {
+ TokStart = CurPtr;
+ // This always consumes at least one character.
+ int CurChar = getNextChar();
+
+ if (isAtStartOfComment(CurChar))
+ return LexLineComment();
+
+ switch (CurChar) {
+ default:
+ // Handle identifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
+ if (isalpha(CurChar) || CurChar == '_' || CurChar == '.')
+ return LexIdentifier();
+
+ // Unknown character, emit an error.
+ return ReturnError(TokStart, "invalid character in input");
+ case EOF: return AsmToken(AsmToken::Eof, StringRef(TokStart, 0));
+ case 0:
+ case ' ':
+ case '\t':
+ // Ignore whitespace.
+ return LexToken();
+ case '\n': // FALL THROUGH.
+ case '\r': // FALL THROUGH.
+ case ';': return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1));
+ case ':': return AsmToken(AsmToken::Colon, StringRef(TokStart, 1));
+ case '+': return AsmToken(AsmToken::Plus, StringRef(TokStart, 1));
+ case '-': return AsmToken(AsmToken::Minus, StringRef(TokStart, 1));
+ case '~': return AsmToken(AsmToken::Tilde, StringRef(TokStart, 1));
+ case '(': return AsmToken(AsmToken::LParen, StringRef(TokStart, 1));
+ case ')': return AsmToken(AsmToken::RParen, StringRef(TokStart, 1));
+ case '[': return AsmToken(AsmToken::LBrac, StringRef(TokStart, 1));
+ case ']': return AsmToken(AsmToken::RBrac, StringRef(TokStart, 1));
+ case '{': return AsmToken(AsmToken::LCurly, StringRef(TokStart, 1));
+ case '}': return AsmToken(AsmToken::RCurly, StringRef(TokStart, 1));
+ case '*': return AsmToken(AsmToken::Star, StringRef(TokStart, 1));
+ case ',': return AsmToken(AsmToken::Comma, StringRef(TokStart, 1));
+ case '$': return AsmToken(AsmToken::Dollar, StringRef(TokStart, 1));
+ case '=':
+ if (*CurPtr == '=')
+ return ++CurPtr, AsmToken(AsmToken::EqualEqual, StringRef(TokStart, 2));
+ return AsmToken(AsmToken::Equal, StringRef(TokStart, 1));
+ case '|':
+ if (*CurPtr == '|')
+ return ++CurPtr, AsmToken(AsmToken::PipePipe, StringRef(TokStart, 2));
+ return AsmToken(AsmToken::Pipe, StringRef(TokStart, 1));
+ case '^': return AsmToken(AsmToken::Caret, StringRef(TokStart, 1));
+ case '&':
+ if (*CurPtr == '&')
+ return ++CurPtr, AsmToken(AsmToken::AmpAmp, StringRef(TokStart, 2));
+ return AsmToken(AsmToken::Amp, StringRef(TokStart, 1));
+ case '!':
+ if (*CurPtr == '=')
+ return ++CurPtr, AsmToken(AsmToken::ExclaimEqual, StringRef(TokStart, 2));
+ return AsmToken(AsmToken::Exclaim, StringRef(TokStart, 1));
+ case '%': return AsmToken(AsmToken::Percent, StringRef(TokStart, 1));
+ case '/': return LexSlash();
+ case '#': return AsmToken(AsmToken::Hash, StringRef(TokStart, 1));
+ case '"': return LexQuote();
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ return LexDigit();
+ case '<':
+ switch (*CurPtr) {
+ case '<': return ++CurPtr, AsmToken(AsmToken::LessLess,
+ StringRef(TokStart, 2));
+ case '=': return ++CurPtr, AsmToken(AsmToken::LessEqual,
+ StringRef(TokStart, 2));
+ case '>': return ++CurPtr, AsmToken(AsmToken::LessGreater,
+ StringRef(TokStart, 2));
+ default: return AsmToken(AsmToken::Less, StringRef(TokStart, 1));
+ }
+ case '>':
+ switch (*CurPtr) {
+ case '>': return ++CurPtr, AsmToken(AsmToken::GreaterGreater,
+ StringRef(TokStart, 2));
+ case '=': return ++CurPtr, AsmToken(AsmToken::GreaterEqual,
+ StringRef(TokStart, 2));
+ default: return AsmToken(AsmToken::Greater, StringRef(TokStart, 1));
+ }
+
+ // TODO: Quoted identifiers (objc methods etc)
+ // local labels: [0-9][:]
+ // Forward/backward labels: [0-9][fb]
+ // Integers, fp constants, character constants.
+ }
+}
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
new file mode 100644
index 0000000..dd438b7
--- /dev/null
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -0,0 +1,1781 @@
+//===- AsmParser.cpp - Parser for Assembly Files --------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class implements the parser for assembly files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCParser/AsmParser.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCValue.h"
+#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetAsmParser.h"
+using namespace llvm;
+
+
+enum { DEFAULT_ADDRSPACE = 0 };
+
+// Mach-O section uniquing.
+//
+// FIXME: Figure out where this should live, it should be shared by
+// TargetLoweringObjectFile.
+typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
+
+AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out,
+ const MCAsmInfo &_MAI)
+ : Lexer(_MAI), Ctx(_Ctx), Out(_Out), SrcMgr(_SM), TargetParser(0),
+ CurBuffer(0), SectionUniquingMap(0) {
+ Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
+
+ // Debugging directives.
+ AddDirectiveHandler(".file", &AsmParser::ParseDirectiveFile);
+ AddDirectiveHandler(".line", &AsmParser::ParseDirectiveLine);
+ AddDirectiveHandler(".loc", &AsmParser::ParseDirectiveLoc);
+}
+
+
+
+AsmParser::~AsmParser() {
+ // If we have the MachO uniquing map, free it.
+ delete (MachOUniqueMapTy*)SectionUniquingMap;
+}
+
+const MCSection *AsmParser::getMachOSection(const StringRef &Segment,
+ const StringRef &Section,
+ unsigned TypeAndAttributes,
+ unsigned Reserved2,
+ SectionKind Kind) const {
+ // We unique sections by their segment/section pair. The returned section
+ // may not have the same flags as the requested section, if so this should be
+ // diagnosed by the client as an error.
+
+ // Create the map if it doesn't already exist.
+ if (SectionUniquingMap == 0)
+ SectionUniquingMap = new MachOUniqueMapTy();
+ MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)SectionUniquingMap;
+
+ // Form the name to look up.
+ SmallString<64> Name;
+ Name += Segment;
+ Name.push_back(',');
+ Name += Section;
+
+ // Do the lookup, if we have a hit, return it.
+ const MCSectionMachO *&Entry = Map[Name.str()];
+
+ // FIXME: This should validate the type and attributes.
+ if (Entry) return Entry;
+
+ // Otherwise, return a new section.
+ return Entry = MCSectionMachO::Create(Segment, Section, TypeAndAttributes,
+ Reserved2, Kind, Ctx);
+}
+
+void AsmParser::Warning(SMLoc L, const Twine &Msg) {
+ PrintMessage(L, Msg.str(), "warning");
+}
+
+bool AsmParser::Error(SMLoc L, const Twine &Msg) {
+ PrintMessage(L, Msg.str(), "error");
+ return true;
+}
+
+bool AsmParser::TokError(const char *Msg) {
+ PrintMessage(Lexer.getLoc(), Msg, "error");
+ return true;
+}
+
+void AsmParser::PrintMessage(SMLoc Loc, const std::string &Msg,
+ const char *Type) const {
+ SrcMgr.PrintMessage(Loc, Msg, Type);
+}
+
+bool AsmParser::EnterIncludeFile(const std::string &Filename) {
+ int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc());
+ if (NewBuf == -1)
+ return true;
+
+ CurBuffer = NewBuf;
+
+ Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
+
+ return false;
+}
+
+const AsmToken &AsmParser::Lex() {
+ const AsmToken *tok = &Lexer.Lex();
+
+ if (tok->is(AsmToken::Eof)) {
+ // If this is the end of an included file, pop the parent file off the
+ // include stack.
+ SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
+ if (ParentIncludeLoc != SMLoc()) {
+ CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc);
+ Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer),
+ ParentIncludeLoc.getPointer());
+ tok = &Lexer.Lex();
+ }
+ }
+
+ if (tok->is(AsmToken::Error))
+ PrintMessage(Lexer.getErrLoc(), Lexer.getErr(), "error");
+
+ return *tok;
+}
+
+bool AsmParser::Run() {
+ // Create the initial section.
+ //
+ // FIXME: Support -n.
+ // FIXME: Target hook & command line option for initial section.
+ Out.SwitchSection(getMachOSection("__TEXT", "__text",
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+ 0, SectionKind()));
+
+
+ // Prime the lexer.
+ Lex();
+
+ bool HadError = false;
+
+ AsmCond StartingCondState = TheCondState;
+
+ // While we have input, parse each statement.
+ while (Lexer.isNot(AsmToken::Eof)) {
+ // Handle conditional assembly here before calling ParseStatement()
+ if (Lexer.getKind() == AsmToken::Identifier) {
+ // If we have an identifier, handle it as the key symbol.
+ AsmToken ID = getTok();
+ SMLoc IDLoc = ID.getLoc();
+ StringRef IDVal = ID.getString();
+
+ if (IDVal == ".if" ||
+ IDVal == ".elseif" ||
+ IDVal == ".else" ||
+ IDVal == ".endif") {
+ if (!ParseConditionalAssemblyDirectives(IDVal, IDLoc))
+ continue;
+ HadError = true;
+ EatToEndOfStatement();
+ continue;
+ }
+ }
+ if (TheCondState.Ignore) {
+ EatToEndOfStatement();
+ continue;
+ }
+
+ if (!ParseStatement()) continue;
+
+ // We had an error, remember it and recover by skipping to the next line.
+ HadError = true;
+ EatToEndOfStatement();
+ }
+
+ if (TheCondState.TheCond != StartingCondState.TheCond ||
+ TheCondState.Ignore != StartingCondState.Ignore)
+ return TokError("unmatched .ifs or .elses");
+
+ if (!HadError)
+ Out.Finish();
+
+ return HadError;
+}
+
+/// ParseConditionalAssemblyDirectives - parse the conditional assembly
+/// directives
+bool AsmParser::ParseConditionalAssemblyDirectives(StringRef Directive,
+ SMLoc DirectiveLoc) {
+ if (Directive == ".if")
+ return ParseDirectiveIf(DirectiveLoc);
+ if (Directive == ".elseif")
+ return ParseDirectiveElseIf(DirectiveLoc);
+ if (Directive == ".else")
+ return ParseDirectiveElse(DirectiveLoc);
+ if (Directive == ".endif")
+ return ParseDirectiveEndIf(DirectiveLoc);
+ return true;
+}
+
+/// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
+void AsmParser::EatToEndOfStatement() {
+ while (Lexer.isNot(AsmToken::EndOfStatement) &&
+ Lexer.isNot(AsmToken::Eof))
+ Lex();
+
+ // Eat EOL.
+ if (Lexer.is(AsmToken::EndOfStatement))
+ Lex();
+}
+
+
+/// ParseParenExpr - Parse a paren expression and return it.
+/// NOTE: This assumes the leading '(' has already been consumed.
+///
+/// parenexpr ::= expr)
+///
+bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
+ if (ParseExpression(Res)) return true;
+ if (Lexer.isNot(AsmToken::RParen))
+ return TokError("expected ')' in parentheses expression");
+ EndLoc = Lexer.getLoc();
+ Lex();
+ return false;
+}
+
+MCSymbol *AsmParser::CreateSymbol(StringRef Name) {
+ if (MCSymbol *S = Ctx.LookupSymbol(Name))
+ return S;
+
+ // If the label starts with L it is an assembler temporary label.
+ if (Name.startswith("L"))
+ return Ctx.CreateTemporarySymbol(Name);
+
+ return Ctx.CreateSymbol(Name);
+}
+
+/// ParsePrimaryExpr - Parse a primary expression and return it.
+/// primaryexpr ::= (parenexpr
+/// primaryexpr ::= symbol
+/// primaryexpr ::= number
+/// primaryexpr ::= ~,+,- primaryexpr
+bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
+ switch (Lexer.getKind()) {
+ default:
+ return TokError("unknown token in expression");
+ case AsmToken::Exclaim:
+ Lex(); // Eat the operator.
+ if (ParsePrimaryExpr(Res, EndLoc))
+ return true;
+ Res = MCUnaryExpr::CreateLNot(Res, getContext());
+ return false;
+ case AsmToken::String:
+ case AsmToken::Identifier: {
+ // This is a symbol reference.
+ MCSymbol *Sym = CreateSymbol(getTok().getIdentifier());
+ EndLoc = Lexer.getLoc();
+ Lex(); // Eat identifier.
+
+ // If this is an absolute variable reference, substitute it now to preserve
+ // semantics in the face of reassignment.
+ if (Sym->getValue() && isa<MCConstantExpr>(Sym->getValue())) {
+ Res = Sym->getValue();
+ return false;
+ }
+
+ // Otherwise create a symbol ref.
+ Res = MCSymbolRefExpr::Create(Sym, getContext());
+ return false;
+ }
+ case AsmToken::Integer:
+ Res = MCConstantExpr::Create(getTok().getIntVal(), getContext());
+ EndLoc = Lexer.getLoc();
+ Lex(); // Eat token.
+ return false;
+ case AsmToken::LParen:
+ Lex(); // Eat the '('.
+ return ParseParenExpr(Res, EndLoc);
+ case AsmToken::Minus:
+ Lex(); // Eat the operator.
+ if (ParsePrimaryExpr(Res, EndLoc))
+ return true;
+ Res = MCUnaryExpr::CreateMinus(Res, getContext());
+ return false;
+ case AsmToken::Plus:
+ Lex(); // Eat the operator.
+ if (ParsePrimaryExpr(Res, EndLoc))
+ return true;
+ Res = MCUnaryExpr::CreatePlus(Res, getContext());
+ return false;
+ case AsmToken::Tilde:
+ Lex(); // Eat the operator.
+ if (ParsePrimaryExpr(Res, EndLoc))
+ return true;
+ Res = MCUnaryExpr::CreateNot(Res, getContext());
+ return false;
+ }
+}
+
+bool AsmParser::ParseExpression(const MCExpr *&Res) {
+ SMLoc EndLoc;
+ return ParseExpression(Res, EndLoc);
+}
+
+/// ParseExpression - Parse an expression and return it.
+///
+/// expr ::= expr +,- expr -> lowest.
+/// expr ::= expr |,^,&,! expr -> middle.
+/// expr ::= expr *,/,%,<<,>> expr -> highest.
+/// expr ::= primaryexpr
+///
+bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
+ Res = 0;
+ return ParsePrimaryExpr(Res, EndLoc) ||
+ ParseBinOpRHS(1, Res, EndLoc);
+}
+
+bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
+ if (ParseParenExpr(Res, EndLoc))
+ return true;
+
+ return false;
+}
+
+bool AsmParser::ParseAbsoluteExpression(int64_t &Res) {
+ const MCExpr *Expr;
+
+ SMLoc StartLoc = Lexer.getLoc();
+ if (ParseExpression(Expr))
+ return true;
+
+ if (!Expr->EvaluateAsAbsolute(Res))
+ return Error(StartLoc, "expected absolute expression");
+
+ return false;
+}
+
+static unsigned getBinOpPrecedence(AsmToken::TokenKind K,
+ MCBinaryExpr::Opcode &Kind) {
+ switch (K) {
+ default:
+ return 0; // not a binop.
+
+ // Lowest Precedence: &&, ||
+ case AsmToken::AmpAmp:
+ Kind = MCBinaryExpr::LAnd;
+ return 1;
+ case AsmToken::PipePipe:
+ Kind = MCBinaryExpr::LOr;
+ return 1;
+
+ // Low Precedence: +, -, ==, !=, <>, <, <=, >, >=
+ case AsmToken::Plus:
+ Kind = MCBinaryExpr::Add;
+ return 2;
+ case AsmToken::Minus:
+ Kind = MCBinaryExpr::Sub;
+ return 2;
+ case AsmToken::EqualEqual:
+ Kind = MCBinaryExpr::EQ;
+ return 2;
+ case AsmToken::ExclaimEqual:
+ case AsmToken::LessGreater:
+ Kind = MCBinaryExpr::NE;
+ return 2;
+ case AsmToken::Less:
+ Kind = MCBinaryExpr::LT;
+ return 2;
+ case AsmToken::LessEqual:
+ Kind = MCBinaryExpr::LTE;
+ return 2;
+ case AsmToken::Greater:
+ Kind = MCBinaryExpr::GT;
+ return 2;
+ case AsmToken::GreaterEqual:
+ Kind = MCBinaryExpr::GTE;
+ return 2;
+
+ // Intermediate Precedence: |, &, ^
+ //
+ // FIXME: gas seems to support '!' as an infix operator?
+ case AsmToken::Pipe:
+ Kind = MCBinaryExpr::Or;
+ return 3;
+ case AsmToken::Caret:
+ Kind = MCBinaryExpr::Xor;
+ return 3;
+ case AsmToken::Amp:
+ Kind = MCBinaryExpr::And;
+ return 3;
+
+ // Highest Precedence: *, /, %, <<, >>
+ case AsmToken::Star:
+ Kind = MCBinaryExpr::Mul;
+ return 4;
+ case AsmToken::Slash:
+ Kind = MCBinaryExpr::Div;
+ return 4;
+ case AsmToken::Percent:
+ Kind = MCBinaryExpr::Mod;
+ return 4;
+ case AsmToken::LessLess:
+ Kind = MCBinaryExpr::Shl;
+ return 4;
+ case AsmToken::GreaterGreater:
+ Kind = MCBinaryExpr::Shr;
+ return 4;
+ }
+}
+
+
+/// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
+/// Res contains the LHS of the expression on input.
+bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
+ SMLoc &EndLoc) {
+ while (1) {
+ MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
+ unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
+
+ // If the next token is lower precedence than we are allowed to eat, return
+ // successfully with what we ate already.
+ if (TokPrec < Precedence)
+ return false;
+
+ Lex();
+
+ // Eat the next primary expression.
+ const MCExpr *RHS;
+ if (ParsePrimaryExpr(RHS, EndLoc)) return true;
+
+ // If BinOp binds less tightly with RHS than the operator after RHS, let
+ // the pending operator take RHS as its LHS.
+ MCBinaryExpr::Opcode Dummy;
+ unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
+ if (TokPrec < NextTokPrec) {
+ if (ParseBinOpRHS(Precedence+1, RHS, EndLoc)) return true;
+ }
+
+ // Merge LHS and RHS according to operator.
+ Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext());
+ }
+}
+
+
+
+
+/// ParseStatement:
+/// ::= EndOfStatement
+/// ::= Label* Directive ...Operands... EndOfStatement
+/// ::= Label* Identifier OperandList* EndOfStatement
+bool AsmParser::ParseStatement() {
+ if (Lexer.is(AsmToken::EndOfStatement)) {
+ Lex();
+ return false;
+ }
+
+ // Statements always start with an identifier.
+ AsmToken ID = getTok();
+ SMLoc IDLoc = ID.getLoc();
+ StringRef IDVal;
+ if (ParseIdentifier(IDVal))
+ return TokError("unexpected token at start of statement");
+
+ // FIXME: Recurse on local labels?
+
+ // See what kind of statement we have.
+ switch (Lexer.getKind()) {
+ case AsmToken::Colon: {
+ // identifier ':' -> Label.
+ Lex();
+
+ // Diagnose attempt to use a variable as a label.
+ //
+ // FIXME: Diagnostics. Note the location of the definition as a label.
+ // FIXME: This doesn't diagnose assignment to a symbol which has been
+ // implicitly marked as external.
+ MCSymbol *Sym = CreateSymbol(IDVal);
+ if (!Sym->isUndefined())
+ return Error(IDLoc, "invalid symbol redefinition");
+
+ // Emit the label.
+ Out.EmitLabel(Sym);
+
+ return ParseStatement();
+ }
+
+ case AsmToken::Equal:
+ // identifier '=' ... -> assignment statement
+ Lex();
+
+ return ParseAssignment(IDVal);
+
+ default: // Normal instruction or directive.
+ break;
+ }
+
+ // Otherwise, we have a normal instruction or directive.
+ if (IDVal[0] == '.') {
+ // FIXME: This should be driven based on a hash lookup and callback.
+ if (IDVal == ".section")
+ return ParseDirectiveDarwinSection();
+ if (IDVal == ".text")
+ // FIXME: This changes behavior based on the -static flag to the
+ // assembler.
+ return ParseDirectiveSectionSwitch("__TEXT", "__text",
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
+ if (IDVal == ".const")
+ return ParseDirectiveSectionSwitch("__TEXT", "__const");
+ if (IDVal == ".static_const")
+ return ParseDirectiveSectionSwitch("__TEXT", "__static_const");
+ if (IDVal == ".cstring")
+ return ParseDirectiveSectionSwitch("__TEXT","__cstring",
+ MCSectionMachO::S_CSTRING_LITERALS);
+ if (IDVal == ".literal4")
+ return ParseDirectiveSectionSwitch("__TEXT", "__literal4",
+ MCSectionMachO::S_4BYTE_LITERALS,
+ 4);
+ if (IDVal == ".literal8")
+ return ParseDirectiveSectionSwitch("__TEXT", "__literal8",
+ MCSectionMachO::S_8BYTE_LITERALS,
+ 8);
+ if (IDVal == ".literal16")
+ return ParseDirectiveSectionSwitch("__TEXT","__literal16",
+ MCSectionMachO::S_16BYTE_LITERALS,
+ 16);
+ if (IDVal == ".constructor")
+ return ParseDirectiveSectionSwitch("__TEXT","__constructor");
+ if (IDVal == ".destructor")
+ return ParseDirectiveSectionSwitch("__TEXT","__destructor");
+ if (IDVal == ".fvmlib_init0")
+ return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init0");
+ if (IDVal == ".fvmlib_init1")
+ return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init1");
+
+ // FIXME: The assembler manual claims that this has the self modify code
+ // flag, at least on x86-32, but that does not appear to be correct.
+ if (IDVal == ".symbol_stub")
+ return ParseDirectiveSectionSwitch("__TEXT","__symbol_stub",
+ MCSectionMachO::S_SYMBOL_STUBS |
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+ // FIXME: Different on PPC and ARM.
+ 0, 16);
+ // FIXME: PowerPC only?
+ if (IDVal == ".picsymbol_stub")
+ return ParseDirectiveSectionSwitch("__TEXT","__picsymbol_stub",
+ MCSectionMachO::S_SYMBOL_STUBS |
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+ 0, 26);
+ if (IDVal == ".data")
+ return ParseDirectiveSectionSwitch("__DATA", "__data");
+ if (IDVal == ".static_data")
+ return ParseDirectiveSectionSwitch("__DATA", "__static_data");
+
+ // FIXME: The section names of these two are misspelled in the assembler
+ // manual.
+ if (IDVal == ".non_lazy_symbol_pointer")
+ return ParseDirectiveSectionSwitch("__DATA", "__nl_symbol_ptr",
+ MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
+ 4);
+ if (IDVal == ".lazy_symbol_pointer")
+ return ParseDirectiveSectionSwitch("__DATA", "__la_symbol_ptr",
+ MCSectionMachO::S_LAZY_SYMBOL_POINTERS,
+ 4);
+
+ if (IDVal == ".dyld")
+ return ParseDirectiveSectionSwitch("__DATA", "__dyld");
+ if (IDVal == ".mod_init_func")
+ return ParseDirectiveSectionSwitch("__DATA", "__mod_init_func",
+ MCSectionMachO::S_MOD_INIT_FUNC_POINTERS,
+ 4);
+ if (IDVal == ".mod_term_func")
+ return ParseDirectiveSectionSwitch("__DATA", "__mod_term_func",
+ MCSectionMachO::S_MOD_TERM_FUNC_POINTERS,
+ 4);
+ if (IDVal == ".const_data")
+ return ParseDirectiveSectionSwitch("__DATA", "__const");
+
+
+ if (IDVal == ".objc_class")
+ return ParseDirectiveSectionSwitch("__OBJC", "__class",
+ MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ if (IDVal == ".objc_meta_class")
+ return ParseDirectiveSectionSwitch("__OBJC", "__meta_class",
+ MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ if (IDVal == ".objc_cat_cls_meth")
+ return ParseDirectiveSectionSwitch("__OBJC", "__cat_cls_meth",
+ MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ if (IDVal == ".objc_cat_inst_meth")
+ return ParseDirectiveSectionSwitch("__OBJC", "__cat_inst_meth",
+ MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ if (IDVal == ".objc_protocol")
+ return ParseDirectiveSectionSwitch("__OBJC", "__protocol",
+ MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ if (IDVal == ".objc_string_object")
+ return ParseDirectiveSectionSwitch("__OBJC", "__string_object",
+ MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ if (IDVal == ".objc_cls_meth")
+ return ParseDirectiveSectionSwitch("__OBJC", "__cls_meth",
+ MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ if (IDVal == ".objc_inst_meth")
+ return ParseDirectiveSectionSwitch("__OBJC", "__inst_meth",
+ MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ if (IDVal == ".objc_cls_refs")
+ return ParseDirectiveSectionSwitch("__OBJC", "__cls_refs",
+ MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
+ MCSectionMachO::S_LITERAL_POINTERS,
+ 4);
+ if (IDVal == ".objc_message_refs")
+ return ParseDirectiveSectionSwitch("__OBJC", "__message_refs",
+ MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
+ MCSectionMachO::S_LITERAL_POINTERS,
+ 4);
+ if (IDVal == ".objc_symbols")
+ return ParseDirectiveSectionSwitch("__OBJC", "__symbols",
+ MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ if (IDVal == ".objc_category")
+ return ParseDirectiveSectionSwitch("__OBJC", "__category",
+ MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ if (IDVal == ".objc_class_vars")
+ return ParseDirectiveSectionSwitch("__OBJC", "__class_vars",
+ MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ if (IDVal == ".objc_instance_vars")
+ return ParseDirectiveSectionSwitch("__OBJC", "__instance_vars",
+ MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ if (IDVal == ".objc_module_info")
+ return ParseDirectiveSectionSwitch("__OBJC", "__module_info",
+ MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
+ if (IDVal == ".objc_class_names")
+ return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
+ MCSectionMachO::S_CSTRING_LITERALS);
+ if (IDVal == ".objc_meth_var_types")
+ return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
+ MCSectionMachO::S_CSTRING_LITERALS);
+ if (IDVal == ".objc_meth_var_names")
+ return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
+ MCSectionMachO::S_CSTRING_LITERALS);
+ if (IDVal == ".objc_selector_strs")
+ return ParseDirectiveSectionSwitch("__OBJC", "__selector_strs",
+ MCSectionMachO::S_CSTRING_LITERALS);
+
+ // Assembler features
+ if (IDVal == ".set")
+ return ParseDirectiveSet();
+
+ // Data directives
+
+ if (IDVal == ".ascii")
+ return ParseDirectiveAscii(false);
+ if (IDVal == ".asciz")
+ return ParseDirectiveAscii(true);
+
+ if (IDVal == ".byte")
+ return ParseDirectiveValue(1);
+ if (IDVal == ".short")
+ return ParseDirectiveValue(2);
+ if (IDVal == ".long")
+ return ParseDirectiveValue(4);
+ if (IDVal == ".quad")
+ return ParseDirectiveValue(8);
+
+ // FIXME: Target hooks for IsPow2.
+ if (IDVal == ".align")
+ return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
+ if (IDVal == ".align32")
+ return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
+ if (IDVal == ".balign")
+ return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
+ if (IDVal == ".balignw")
+ return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
+ if (IDVal == ".balignl")
+ return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
+ if (IDVal == ".p2align")
+ return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
+ if (IDVal == ".p2alignw")
+ return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
+ if (IDVal == ".p2alignl")
+ return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
+
+ if (IDVal == ".org")
+ return ParseDirectiveOrg();
+
+ if (IDVal == ".fill")
+ return ParseDirectiveFill();
+ if (IDVal == ".space")
+ return ParseDirectiveSpace();
+
+ // Symbol attribute directives
+
+ if (IDVal == ".globl" || IDVal == ".global")
+ return ParseDirectiveSymbolAttribute(MCSA_Global);
+ if (IDVal == ".hidden")
+ return ParseDirectiveSymbolAttribute(MCSA_Hidden);
+ if (IDVal == ".indirect_symbol")
+ return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol);
+ if (IDVal == ".internal")
+ return ParseDirectiveSymbolAttribute(MCSA_Internal);
+ if (IDVal == ".lazy_reference")
+ return ParseDirectiveSymbolAttribute(MCSA_LazyReference);
+ if (IDVal == ".no_dead_strip")
+ return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip);
+ if (IDVal == ".private_extern")
+ return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern);
+ if (IDVal == ".protected")
+ return ParseDirectiveSymbolAttribute(MCSA_Protected);
+ if (IDVal == ".reference")
+ return ParseDirectiveSymbolAttribute(MCSA_Reference);
+ if (IDVal == ".weak")
+ return ParseDirectiveSymbolAttribute(MCSA_Weak);
+ if (IDVal == ".weak_definition")
+ return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition);
+ if (IDVal == ".weak_reference")
+ return ParseDirectiveSymbolAttribute(MCSA_WeakReference);
+
+ if (IDVal == ".comm")
+ return ParseDirectiveComm(/*IsLocal=*/false);
+ if (IDVal == ".lcomm")
+ return ParseDirectiveComm(/*IsLocal=*/true);
+ if (IDVal == ".zerofill")
+ return ParseDirectiveDarwinZerofill();
+ if (IDVal == ".desc")
+ return ParseDirectiveDarwinSymbolDesc();
+ if (IDVal == ".lsym")
+ return ParseDirectiveDarwinLsym();
+
+ if (IDVal == ".subsections_via_symbols")
+ return ParseDirectiveDarwinSubsectionsViaSymbols();
+ if (IDVal == ".abort")
+ return ParseDirectiveAbort();
+ if (IDVal == ".include")
+ return ParseDirectiveInclude();
+ if (IDVal == ".dump")
+ return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsDump=*/true);
+ if (IDVal == ".load")
+ return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsLoad=*/false);
+
+ // Look up the handler in the handler table,
+ bool(AsmParser::*Handler)(StringRef, SMLoc) = DirectiveMap[IDVal];
+ if (Handler)
+ return (this->*Handler)(IDVal, IDLoc);
+
+ // Target hook for parsing target specific directives.
+ if (!getTargetParser().ParseDirective(ID))
+ return false;
+
+ Warning(IDLoc, "ignoring directive for now");
+ EatToEndOfStatement();
+ return false;
+ }
+
+
+ SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
+ if (getTargetParser().ParseInstruction(IDVal, IDLoc, ParsedOperands))
+ // FIXME: Leaking ParsedOperands on failure.
+ return true;
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ // FIXME: Leaking ParsedOperands on failure.
+ return TokError("unexpected token in argument list");
+
+ // Eat the end of statement marker.
+ Lex();
+
+
+ MCInst Inst;
+
+ bool MatchFail = getTargetParser().MatchInstruction(ParsedOperands, Inst);
+
+ // Free any parsed operands.
+ for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
+ delete ParsedOperands[i];
+
+ if (MatchFail) {
+ // FIXME: We should give nicer diagnostics about the exact failure.
+ Error(IDLoc, "unrecognized instruction");
+ return true;
+ }
+
+ // Instruction is good, process it.
+ Out.EmitInstruction(Inst);
+
+ // Skip to end of line for now.
+ return false;
+}
+
+bool AsmParser::ParseAssignment(const StringRef &Name) {
+ // FIXME: Use better location, we should use proper tokens.
+ SMLoc EqualLoc = Lexer.getLoc();
+
+ const MCExpr *Value;
+ SMLoc StartLoc = Lexer.getLoc();
+ if (ParseExpression(Value))
+ return true;
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in assignment");
+
+ // Eat the end of statement marker.
+ Lex();
+
+ // Validate that the LHS is allowed to be a variable (either it has not been
+ // used as a symbol, or it is an absolute symbol).
+ MCSymbol *Sym = getContext().LookupSymbol(Name);
+ if (Sym) {
+ // Diagnose assignment to a label.
+ //
+ // FIXME: Diagnostics. Note the location of the definition as a label.
+ // FIXME: Diagnose assignment to protected identifier (e.g., register name).
+ if (!Sym->isUndefined() && !Sym->isAbsolute())
+ return Error(EqualLoc, "redefinition of '" + Name + "'");
+ else if (!Sym->isVariable())
+ return Error(EqualLoc, "invalid assignment to '" + Name + "'");
+ else if (!isa<MCConstantExpr>(Sym->getValue()))
+ return Error(EqualLoc, "invalid reassignment of non-absolute variable '" +
+ Name + "'");
+ } else
+ Sym = CreateSymbol(Name);
+
+ // FIXME: Handle '.'.
+
+ // Do the assignment.
+ Out.EmitAssignment(Sym, Value);
+
+ return false;
+}
+
+/// ParseIdentifier:
+/// ::= identifier
+/// ::= string
+bool AsmParser::ParseIdentifier(StringRef &Res) {
+ if (Lexer.isNot(AsmToken::Identifier) &&
+ Lexer.isNot(AsmToken::String))
+ return true;
+
+ Res = getTok().getIdentifier();
+
+ Lex(); // Consume the identifier token.
+
+ return false;
+}
+
+/// ParseDirectiveSet:
+/// ::= .set identifier ',' expression
+bool AsmParser::ParseDirectiveSet() {
+ StringRef Name;
+
+ if (ParseIdentifier(Name))
+ return TokError("expected identifier after '.set' directive");
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in '.set'");
+ Lex();
+
+ return ParseAssignment(Name);
+}
+
+/// ParseDirectiveSection:
+/// ::= .section identifier (',' identifier)*
+/// FIXME: This should actually parse out the segment, section, attributes and
+/// sizeof_stub fields.
+bool AsmParser::ParseDirectiveDarwinSection() {
+ SMLoc Loc = Lexer.getLoc();
+
+ StringRef SectionName;
+ if (ParseIdentifier(SectionName))
+ return Error(Loc, "expected identifier after '.section' directive");
+
+ // Verify there is a following comma.
+ if (!Lexer.is(AsmToken::Comma))
+ return TokError("unexpected token in '.section' directive");
+
+ std::string SectionSpec = SectionName;
+ SectionSpec += ",";
+
+ // Add all the tokens until the end of the line, ParseSectionSpecifier will
+ // handle this.
+ StringRef EOL = Lexer.LexUntilEndOfStatement();
+ SectionSpec.append(EOL.begin(), EOL.end());
+
+ Lex();
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.section' directive");
+ Lex();
+
+
+ StringRef Segment, Section;
+ unsigned TAA, StubSize;
+ std::string ErrorStr =
+ MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
+ TAA, StubSize);
+
+ if (!ErrorStr.empty())
+ return Error(Loc, ErrorStr.c_str());
+
+ // FIXME: Arch specific.
+ Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize,
+ SectionKind()));
+ return false;
+}
+
+/// ParseDirectiveSectionSwitch -
+bool AsmParser::ParseDirectiveSectionSwitch(const char *Segment,
+ const char *Section,
+ unsigned TAA, unsigned Align,
+ unsigned StubSize) {
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in section switching directive");
+ Lex();
+
+ // FIXME: Arch specific.
+ Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize,
+ SectionKind()));
+
+ // Set the implicit alignment, if any.
+ //
+ // FIXME: This isn't really what 'as' does; I think it just uses the implicit
+ // alignment on the section (e.g., if one manually inserts bytes into the
+ // section, then just issueing the section switch directive will not realign
+ // the section. However, this is arguably more reasonable behavior, and there
+ // is no good reason for someone to intentionally emit incorrectly sized
+ // values into the implicitly aligned sections.
+ if (Align)
+ Out.EmitValueToAlignment(Align, 0, 1, 0);
+
+ return false;
+}
+
+bool AsmParser::ParseEscapedString(std::string &Data) {
+ assert(Lexer.is(AsmToken::String) && "Unexpected current token!");
+
+ Data = "";
+ StringRef Str = getTok().getStringContents();
+ for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+ if (Str[i] != '\\') {
+ Data += Str[i];
+ continue;
+ }
+
+ // Recognize escaped characters. Note that this escape semantics currently
+ // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes.
+ ++i;
+ if (i == e)
+ return TokError("unexpected backslash at end of string");
+
+ // Recognize octal sequences.
+ if ((unsigned) (Str[i] - '0') <= 7) {
+ // Consume up to three octal characters.
+ unsigned Value = Str[i] - '0';
+
+ if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
+ ++i;
+ Value = Value * 8 + (Str[i] - '0');
+
+ if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
+ ++i;
+ Value = Value * 8 + (Str[i] - '0');
+ }
+ }
+
+ if (Value > 255)
+ return TokError("invalid octal escape sequence (out of range)");
+
+ Data += (unsigned char) Value;
+ continue;
+ }
+
+ // Otherwise recognize individual escapes.
+ switch (Str[i]) {
+ default:
+ // Just reject invalid escape sequences for now.
+ return TokError("invalid escape sequence (unrecognized character)");
+
+ case 'b': Data += '\b'; break;
+ case 'f': Data += '\f'; break;
+ case 'n': Data += '\n'; break;
+ case 'r': Data += '\r'; break;
+ case 't': Data += '\t'; break;
+ case '"': Data += '"'; break;
+ case '\\': Data += '\\'; break;
+ }
+ }
+
+ return false;
+}
+
+/// ParseDirectiveAscii:
+/// ::= ( .ascii | .asciz ) [ "string" ( , "string" )* ]
+bool AsmParser::ParseDirectiveAscii(bool ZeroTerminated) {
+ if (Lexer.isNot(AsmToken::EndOfStatement)) {
+ for (;;) {
+ if (Lexer.isNot(AsmToken::String))
+ return TokError("expected string in '.ascii' or '.asciz' directive");
+
+ std::string Data;
+ if (ParseEscapedString(Data))
+ return true;
+
+ Out.EmitBytes(Data, DEFAULT_ADDRSPACE);
+ if (ZeroTerminated)
+ Out.EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE);
+
+ Lex();
+
+ if (Lexer.is(AsmToken::EndOfStatement))
+ break;
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in '.ascii' or '.asciz' directive");
+ Lex();
+ }
+ }
+
+ Lex();
+ return false;
+}
+
+/// ParseDirectiveValue
+/// ::= (.byte | .short | ... ) [ expression (, expression)* ]
+bool AsmParser::ParseDirectiveValue(unsigned Size) {
+ if (Lexer.isNot(AsmToken::EndOfStatement)) {
+ for (;;) {
+ const MCExpr *Value;
+ SMLoc ATTRIBUTE_UNUSED StartLoc = Lexer.getLoc();
+ if (ParseExpression(Value))
+ return true;
+
+ Out.EmitValue(Value, Size, DEFAULT_ADDRSPACE);
+
+ if (Lexer.is(AsmToken::EndOfStatement))
+ break;
+
+ // FIXME: Improve diagnostic.
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+ }
+ }
+
+ Lex();
+ return false;
+}
+
+/// ParseDirectiveSpace
+/// ::= .space expression [ , expression ]
+bool AsmParser::ParseDirectiveSpace() {
+ int64_t NumBytes;
+ if (ParseAbsoluteExpression(NumBytes))
+ return true;
+
+ int64_t FillExpr = 0;
+ bool HasFillExpr = false;
+ if (Lexer.isNot(AsmToken::EndOfStatement)) {
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in '.space' directive");
+ Lex();
+
+ if (ParseAbsoluteExpression(FillExpr))
+ return true;
+
+ HasFillExpr = true;
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.space' directive");
+ }
+
+ Lex();
+
+ if (NumBytes <= 0)
+ return TokError("invalid number of bytes in '.space' directive");
+
+ // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
+ Out.EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE);
+
+ return false;
+}
+
+/// ParseDirectiveFill
+/// ::= .fill expression , expression , expression
+bool AsmParser::ParseDirectiveFill() {
+ int64_t NumValues;
+ if (ParseAbsoluteExpression(NumValues))
+ return true;
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in '.fill' directive");
+ Lex();
+
+ int64_t FillSize;
+ if (ParseAbsoluteExpression(FillSize))
+ return true;
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in '.fill' directive");
+ Lex();
+
+ int64_t FillExpr;
+ if (ParseAbsoluteExpression(FillExpr))
+ return true;
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.fill' directive");
+
+ Lex();
+
+ if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8)
+ return TokError("invalid '.fill' size, expected 1, 2, 4, or 8");
+
+ for (uint64_t i = 0, e = NumValues; i != e; ++i)
+ Out.EmitValue(MCConstantExpr::Create(FillExpr, getContext()), FillSize,
+ DEFAULT_ADDRSPACE);
+
+ return false;
+}
+
+/// ParseDirectiveOrg
+/// ::= .org expression [ , expression ]
+bool AsmParser::ParseDirectiveOrg() {
+ const MCExpr *Offset;
+ SMLoc StartLoc = Lexer.getLoc();
+ if (ParseExpression(Offset))
+ return true;
+
+ // Parse optional fill expression.
+ int64_t FillExpr = 0;
+ if (Lexer.isNot(AsmToken::EndOfStatement)) {
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in '.org' directive");
+ Lex();
+
+ if (ParseAbsoluteExpression(FillExpr))
+ return true;
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.org' directive");
+ }
+
+ Lex();
+
+ // FIXME: Only limited forms of relocatable expressions are accepted here, it
+ // has to be relative to the current section.
+ Out.EmitValueToOffset(Offset, FillExpr);
+
+ return false;
+}
+
+/// ParseDirectiveAlign
+/// ::= {.align, ...} expression [ , expression [ , expression ]]
+bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
+ SMLoc AlignmentLoc = Lexer.getLoc();
+ int64_t Alignment;
+ if (ParseAbsoluteExpression(Alignment))
+ return true;
+
+ SMLoc MaxBytesLoc;
+ bool HasFillExpr = false;
+ int64_t FillExpr = 0;
+ int64_t MaxBytesToFill = 0;
+ if (Lexer.isNot(AsmToken::EndOfStatement)) {
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ // The fill expression can be omitted while specifying a maximum number of
+ // alignment bytes, e.g:
+ // .align 3,,4
+ if (Lexer.isNot(AsmToken::Comma)) {
+ HasFillExpr = true;
+ if (ParseAbsoluteExpression(FillExpr))
+ return true;
+ }
+
+ if (Lexer.isNot(AsmToken::EndOfStatement)) {
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ MaxBytesLoc = Lexer.getLoc();
+ if (ParseAbsoluteExpression(MaxBytesToFill))
+ return true;
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in directive");
+ }
+ }
+
+ Lex();
+
+ if (!HasFillExpr) {
+ // FIXME: Sometimes fill with nop.
+ FillExpr = 0;
+ }
+
+ // Compute alignment in bytes.
+ if (IsPow2) {
+ // FIXME: Diagnose overflow.
+ if (Alignment >= 32) {
+ Error(AlignmentLoc, "invalid alignment value");
+ Alignment = 31;
+ }
+
+ Alignment = 1ULL << Alignment;
+ }
+
+ // Diagnose non-sensical max bytes to align.
+ if (MaxBytesLoc.isValid()) {
+ if (MaxBytesToFill < 1) {
+ Error(MaxBytesLoc, "alignment directive can never be satisfied in this "
+ "many bytes, ignoring maximum bytes expression");
+ MaxBytesToFill = 0;
+ }
+
+ if (MaxBytesToFill >= Alignment) {
+ Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and "
+ "has no effect");
+ MaxBytesToFill = 0;
+ }
+ }
+
+ // FIXME: Target specific behavior about how the "extra" bytes are filled.
+ Out.EmitValueToAlignment(Alignment, FillExpr, ValueSize, MaxBytesToFill);
+
+ return false;
+}
+
+/// ParseDirectiveSymbolAttribute
+/// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
+bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
+ if (Lexer.isNot(AsmToken::EndOfStatement)) {
+ for (;;) {
+ StringRef Name;
+
+ if (ParseIdentifier(Name))
+ return TokError("expected identifier in directive");
+
+ MCSymbol *Sym = CreateSymbol(Name);
+
+ Out.EmitSymbolAttribute(Sym, Attr);
+
+ if (Lexer.is(AsmToken::EndOfStatement))
+ break;
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+ }
+ }
+
+ Lex();
+ return false;
+}
+
+/// ParseDirectiveDarwinSymbolDesc
+/// ::= .desc identifier , expression
+bool AsmParser::ParseDirectiveDarwinSymbolDesc() {
+ StringRef Name;
+ if (ParseIdentifier(Name))
+ return TokError("expected identifier in directive");
+
+ // Handle the identifier as the key symbol.
+ MCSymbol *Sym = CreateSymbol(Name);
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in '.desc' directive");
+ Lex();
+
+ SMLoc DescLoc = Lexer.getLoc();
+ int64_t DescValue;
+ if (ParseAbsoluteExpression(DescValue))
+ return true;
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.desc' directive");
+
+ Lex();
+
+ // Set the n_desc field of this Symbol to this DescValue
+ Out.EmitSymbolDesc(Sym, DescValue);
+
+ return false;
+}
+
+/// ParseDirectiveComm
+/// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
+bool AsmParser::ParseDirectiveComm(bool IsLocal) {
+ SMLoc IDLoc = Lexer.getLoc();
+ StringRef Name;
+ if (ParseIdentifier(Name))
+ return TokError("expected identifier in directive");
+
+ // Handle the identifier as the key symbol.
+ MCSymbol *Sym = CreateSymbol(Name);
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ int64_t Size;
+ SMLoc SizeLoc = Lexer.getLoc();
+ if (ParseAbsoluteExpression(Size))
+ return true;
+
+ int64_t Pow2Alignment = 0;
+ SMLoc Pow2AlignmentLoc;
+ if (Lexer.is(AsmToken::Comma)) {
+ Lex();
+ Pow2AlignmentLoc = Lexer.getLoc();
+ if (ParseAbsoluteExpression(Pow2Alignment))
+ return true;
+
+ // If this target takes alignments in bytes (not log) validate and convert.
+ if (Lexer.getMAI().getAlignmentIsInBytes()) {
+ if (!isPowerOf2_64(Pow2Alignment))
+ return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
+ Pow2Alignment = Log2_64(Pow2Alignment);
+ }
+ }
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.comm' or '.lcomm' directive");
+
+ Lex();
+
+ // NOTE: a size of zero for a .comm should create a undefined symbol
+ // but a size of .lcomm creates a bss symbol of size zero.
+ if (Size < 0)
+ return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
+ "be less than zero");
+
+ // NOTE: The alignment in the directive is a power of 2 value, the assember
+ // may internally end up wanting an alignment in bytes.
+ // FIXME: Diagnose overflow.
+ if (Pow2Alignment < 0)
+ return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
+ "alignment, can't be less than zero");
+
+ if (!Sym->isUndefined())
+ return Error(IDLoc, "invalid symbol redefinition");
+
+ // '.lcomm' is equivalent to '.zerofill'.
+ // Create the Symbol as a common or local common with Size and Pow2Alignment
+ if (IsLocal) {
+ Out.EmitZerofill(getMachOSection("__DATA", "__bss",
+ MCSectionMachO::S_ZEROFILL, 0,
+ SectionKind()),
+ Sym, Size, 1 << Pow2Alignment);
+ return false;
+ }
+
+ Out.EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
+ return false;
+}
+
+/// ParseDirectiveDarwinZerofill
+/// ::= .zerofill segname , sectname [, identifier , size_expression [
+/// , align_expression ]]
+bool AsmParser::ParseDirectiveDarwinZerofill() {
+ // FIXME: Handle quoted names here.
+
+ if (Lexer.isNot(AsmToken::Identifier))
+ return TokError("expected segment name after '.zerofill' directive");
+ StringRef Segment = getTok().getString();
+ Lex();
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ if (Lexer.isNot(AsmToken::Identifier))
+ return TokError("expected section name after comma in '.zerofill' "
+ "directive");
+ StringRef Section = getTok().getString();
+ Lex();
+
+ // If this is the end of the line all that was wanted was to create the
+ // the section but with no symbol.
+ if (Lexer.is(AsmToken::EndOfStatement)) {
+ // Create the zerofill section but no symbol
+ Out.EmitZerofill(getMachOSection(Segment, Section,
+ MCSectionMachO::S_ZEROFILL, 0,
+ SectionKind()));
+ return false;
+ }
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ if (Lexer.isNot(AsmToken::Identifier))
+ return TokError("expected identifier in directive");
+
+ // handle the identifier as the key symbol.
+ SMLoc IDLoc = Lexer.getLoc();
+ MCSymbol *Sym = CreateSymbol(getTok().getString());
+ Lex();
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ int64_t Size;
+ SMLoc SizeLoc = Lexer.getLoc();
+ if (ParseAbsoluteExpression(Size))
+ return true;
+
+ int64_t Pow2Alignment = 0;
+ SMLoc Pow2AlignmentLoc;
+ if (Lexer.is(AsmToken::Comma)) {
+ Lex();
+ Pow2AlignmentLoc = Lexer.getLoc();
+ if (ParseAbsoluteExpression(Pow2Alignment))
+ return true;
+ }
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.zerofill' directive");
+
+ Lex();
+
+ if (Size < 0)
+ return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
+ "than zero");
+
+ // NOTE: The alignment in the directive is a power of 2 value, the assember
+ // may internally end up wanting an alignment in bytes.
+ // FIXME: Diagnose overflow.
+ if (Pow2Alignment < 0)
+ return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
+ "can't be less than zero");
+
+ if (!Sym->isUndefined())
+ return Error(IDLoc, "invalid symbol redefinition");
+
+ // Create the zerofill Symbol with Size and Pow2Alignment
+ //
+ // FIXME: Arch specific.
+ Out.EmitZerofill(getMachOSection(Segment, Section,
+ MCSectionMachO::S_ZEROFILL, 0,
+ SectionKind()),
+ Sym, Size, 1 << Pow2Alignment);
+
+ return false;
+}
+
+/// ParseDirectiveDarwinSubsectionsViaSymbols
+/// ::= .subsections_via_symbols
+bool AsmParser::ParseDirectiveDarwinSubsectionsViaSymbols() {
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.subsections_via_symbols' directive");
+
+ Lex();
+
+ Out.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
+
+ return false;
+}
+
+/// ParseDirectiveAbort
+/// ::= .abort [ "abort_string" ]
+bool AsmParser::ParseDirectiveAbort() {
+ // FIXME: Use loc from directive.
+ SMLoc Loc = Lexer.getLoc();
+
+ StringRef Str = "";
+ if (Lexer.isNot(AsmToken::EndOfStatement)) {
+ if (Lexer.isNot(AsmToken::String))
+ return TokError("expected string in '.abort' directive");
+
+ Str = getTok().getString();
+
+ Lex();
+ }
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.abort' directive");
+
+ Lex();
+
+ // FIXME: Handle here.
+ if (Str.empty())
+ Error(Loc, ".abort detected. Assembly stopping.");
+ else
+ Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
+
+ return false;
+}
+
+/// ParseDirectiveLsym
+/// ::= .lsym identifier , expression
+bool AsmParser::ParseDirectiveDarwinLsym() {
+ StringRef Name;
+ if (ParseIdentifier(Name))
+ return TokError("expected identifier in directive");
+
+ // Handle the identifier as the key symbol.
+ MCSymbol *Sym = CreateSymbol(Name);
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in '.lsym' directive");
+ Lex();
+
+ const MCExpr *Value;
+ SMLoc StartLoc = Lexer.getLoc();
+ if (ParseExpression(Value))
+ return true;
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.lsym' directive");
+
+ Lex();
+
+ // We don't currently support this directive.
+ //
+ // FIXME: Diagnostic location!
+ (void) Sym;
+ return TokError("directive '.lsym' is unsupported");
+}
+
+/// ParseDirectiveInclude
+/// ::= .include "filename"
+bool AsmParser::ParseDirectiveInclude() {
+ if (Lexer.isNot(AsmToken::String))
+ return TokError("expected string in '.include' directive");
+
+ std::string Filename = getTok().getString();
+ SMLoc IncludeLoc = Lexer.getLoc();
+ Lex();
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.include' directive");
+
+ // Strip the quotes.
+ Filename = Filename.substr(1, Filename.size()-2);
+
+ // Attempt to switch the lexer to the included file before consuming the end
+ // of statement to avoid losing it when we switch.
+ if (EnterIncludeFile(Filename)) {
+ PrintMessage(IncludeLoc,
+ "Could not find include file '" + Filename + "'",
+ "error");
+ return true;
+ }
+
+ return false;
+}
+
+/// ParseDirectiveDarwinDumpOrLoad
+/// ::= ( .dump | .load ) "filename"
+bool AsmParser::ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump) {
+ if (Lexer.isNot(AsmToken::String))
+ return TokError("expected string in '.dump' or '.load' directive");
+
+ Lex();
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.dump' or '.load' directive");
+
+ Lex();
+
+ // FIXME: If/when .dump and .load are implemented they will be done in the
+ // the assembly parser and not have any need for an MCStreamer API.
+ if (IsDump)
+ Warning(IDLoc, "ignoring directive .dump for now");
+ else
+ Warning(IDLoc, "ignoring directive .load for now");
+
+ return false;
+}
+
+/// ParseDirectiveIf
+/// ::= .if expression
+bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
+ // Consume the identifier that was the .if directive
+ Lex();
+
+ TheCondStack.push_back(TheCondState);
+ TheCondState.TheCond = AsmCond::IfCond;
+ if(TheCondState.Ignore) {
+ EatToEndOfStatement();
+ }
+ else {
+ int64_t ExprValue;
+ if (ParseAbsoluteExpression(ExprValue))
+ return true;
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.if' directive");
+
+ Lex();
+
+ TheCondState.CondMet = ExprValue;
+ TheCondState.Ignore = !TheCondState.CondMet;
+ }
+
+ return false;
+}
+
+/// ParseDirectiveElseIf
+/// ::= .elseif expression
+bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
+ if (TheCondState.TheCond != AsmCond::IfCond &&
+ TheCondState.TheCond != AsmCond::ElseIfCond)
+ Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
+ " an .elseif");
+ TheCondState.TheCond = AsmCond::ElseIfCond;
+
+ // Consume the identifier that was the .elseif directive
+ Lex();
+
+ bool LastIgnoreState = false;
+ if (!TheCondStack.empty())
+ LastIgnoreState = TheCondStack.back().Ignore;
+ if (LastIgnoreState || TheCondState.CondMet) {
+ TheCondState.Ignore = true;
+ EatToEndOfStatement();
+ }
+ else {
+ int64_t ExprValue;
+ if (ParseAbsoluteExpression(ExprValue))
+ return true;
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.elseif' directive");
+
+ Lex();
+ TheCondState.CondMet = ExprValue;
+ TheCondState.Ignore = !TheCondState.CondMet;
+ }
+
+ return false;
+}
+
+/// ParseDirectiveElse
+/// ::= .else
+bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
+ // Consume the identifier that was the .else directive
+ Lex();
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.else' directive");
+
+ Lex();
+
+ if (TheCondState.TheCond != AsmCond::IfCond &&
+ TheCondState.TheCond != AsmCond::ElseIfCond)
+ Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
+ ".elseif");
+ TheCondState.TheCond = AsmCond::ElseCond;
+ bool LastIgnoreState = false;
+ if (!TheCondStack.empty())
+ LastIgnoreState = TheCondStack.back().Ignore;
+ if (LastIgnoreState || TheCondState.CondMet)
+ TheCondState.Ignore = true;
+ else
+ TheCondState.Ignore = false;
+
+ return false;
+}
+
+/// ParseDirectiveEndIf
+/// ::= .endif
+bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
+ // Consume the identifier that was the .endif directive
+ Lex();
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.endif' directive");
+
+ Lex();
+
+ if ((TheCondState.TheCond == AsmCond::NoCond) ||
+ TheCondStack.empty())
+ Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
+ ".else");
+ if (!TheCondStack.empty()) {
+ TheCondState = TheCondStack.back();
+ TheCondStack.pop_back();
+ }
+
+ return false;
+}
+
+/// ParseDirectiveFile
+/// ::= .file [number] string
+bool AsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
+ // FIXME: I'm not sure what this is.
+ int64_t FileNumber = -1;
+ if (Lexer.is(AsmToken::Integer)) {
+ FileNumber = getTok().getIntVal();
+ Lex();
+
+ if (FileNumber < 1)
+ return TokError("file number less than one");
+ }
+
+ if (Lexer.isNot(AsmToken::String))
+ return TokError("unexpected token in '.file' directive");
+
+ StringRef ATTRIBUTE_UNUSED FileName = getTok().getString();
+ Lex();
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.file' directive");
+
+ // FIXME: Do something with the .file.
+
+ return false;
+}
+
+/// ParseDirectiveLine
+/// ::= .line [number]
+bool AsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) {
+ if (Lexer.isNot(AsmToken::EndOfStatement)) {
+ if (Lexer.isNot(AsmToken::Integer))
+ return TokError("unexpected token in '.line' directive");
+
+ int64_t LineNumber = getTok().getIntVal();
+ (void) LineNumber;
+ Lex();
+
+ // FIXME: Do something with the .line.
+ }
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.file' directive");
+
+ return false;
+}
+
+
+/// ParseDirectiveLoc
+/// ::= .loc number [number [number]]
+bool AsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
+ if (Lexer.isNot(AsmToken::Integer))
+ return TokError("unexpected token in '.loc' directive");
+
+ // FIXME: What are these fields?
+ int64_t FileNumber = getTok().getIntVal();
+ (void) FileNumber;
+ // FIXME: Validate file.
+
+ Lex();
+ if (Lexer.isNot(AsmToken::EndOfStatement)) {
+ if (Lexer.isNot(AsmToken::Integer))
+ return TokError("unexpected token in '.loc' directive");
+
+ int64_t Param2 = getTok().getIntVal();
+ (void) Param2;
+ Lex();
+
+ if (Lexer.isNot(AsmToken::EndOfStatement)) {
+ if (Lexer.isNot(AsmToken::Integer))
+ return TokError("unexpected token in '.loc' directive");
+
+ int64_t Param3 = getTok().getIntVal();
+ (void) Param3;
+ Lex();
+
+ // FIXME: Do something with the .loc.
+ }
+ }
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.file' directive");
+
+ return false;
+}
+
diff --git a/lib/MC/MCParser/CMakeLists.txt b/lib/MC/MCParser/CMakeLists.txt
new file mode 100644
index 0000000..a5c0818
--- /dev/null
+++ b/lib/MC/MCParser/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_llvm_library(LLVMMCParser
+ AsmLexer.cpp
+ AsmParser.cpp
+ MCAsmLexer.cpp
+ MCAsmParser.cpp
+ TargetAsmParser.cpp
+ )
diff --git a/lib/MC/MCAsmLexer.cpp b/lib/MC/MCParser/MCAsmLexer.cpp
index 1e34ed6..e5b2955 100644
--- a/lib/MC/MCAsmLexer.cpp
+++ b/lib/MC/MCParser/MCAsmLexer.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/Support/SourceMgr.h"
using namespace llvm;
diff --git a/lib/MC/MCParser/MCAsmParser.cpp b/lib/MC/MCParser/MCAsmParser.cpp
new file mode 100644
index 0000000..b8c2054
--- /dev/null
+++ b/lib/MC/MCParser/MCAsmParser.cpp
@@ -0,0 +1,35 @@
+//===-- MCAsmParser.cpp - Abstract Asm Parser Interface -------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
+#include "llvm/Support/SourceMgr.h"
+using namespace llvm;
+
+MCAsmParser::MCAsmParser() {
+}
+
+MCAsmParser::~MCAsmParser() {
+}
+
+const AsmToken &MCAsmParser::getTok() {
+ return getLexer().getTok();
+}
+
+bool MCAsmParser::ParseExpression(const MCExpr *&Res) {
+ SMLoc L;
+ return ParseExpression(Res, L);
+}
+
+/// getStartLoc - Get the location of the first token of this operand.
+SMLoc MCParsedAsmOperand::getStartLoc() const { return SMLoc(); }
+SMLoc MCParsedAsmOperand::getEndLoc() const { return SMLoc(); }
+
+
diff --git a/lib/MC/MCParser/Makefile b/lib/MC/MCParser/Makefile
new file mode 100644
index 0000000..e4eb483
--- /dev/null
+++ b/lib/MC/MCParser/Makefile
@@ -0,0 +1,16 @@
+##===- lib/MC/MCParser/Makefile ----------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+LIBRARYNAME = LLVMMCParser
+BUILD_ARCHIVE := 1
+CXXFLAGS = -fno-rtti
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/MC/TargetAsmParser.cpp b/lib/MC/MCParser/TargetAsmParser.cpp
index 05760c9..05760c9 100644
--- a/lib/MC/TargetAsmParser.cpp
+++ b/lib/MC/MCParser/TargetAsmParser.cpp
diff --git a/lib/MC/MCSectionELF.cpp b/lib/MC/MCSectionELF.cpp
index 4d520ec..ebfe269 100644
--- a/lib/MC/MCSectionELF.cpp
+++ b/lib/MC/MCSectionELF.cpp
@@ -22,14 +22,12 @@ Create(StringRef Section, unsigned Type, unsigned Flags,
// ShouldOmitSectionDirective - Decides whether a '.section' directive
// should be printed before the section name
-bool MCSectionELF::ShouldOmitSectionDirective(const char *Name,
+bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name,
const MCAsmInfo &MAI) const {
// FIXME: Does .section .bss/.data/.text work everywhere??
- if (strcmp(Name, ".text") == 0 ||
- strcmp(Name, ".data") == 0 ||
- (strcmp(Name, ".bss") == 0 &&
- !MAI.usesELFSectionDirectiveForBSS()))
+ if (Name == ".text" || Name == ".data" ||
+ (Name == ".bss" && !MAI.usesELFSectionDirectiveForBSS()))
return true;
return false;
@@ -46,7 +44,7 @@ bool MCSectionELF::ShouldPrintSectionType(unsigned Ty) const {
void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const {
- if (ShouldOmitSectionDirective(SectionName.c_str(), MAI)) {
+ if (ShouldOmitSectionDirective(SectionName, MAI)) {
OS << '\t' << getSectionName() << '\n';
return;
}
@@ -128,7 +126,7 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
// header index.
bool MCSectionELF::HasCommonSymbols() const {
- if (strncmp(SectionName.c_str(), ".gnu.linkonce.", 14) == 0)
+ if (StringRef(SectionName).startswith(".gnu.linkonce."))
return true;
return false;
diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp
index 8a6dcda..15b3079 100644
--- a/lib/MC/MCStreamer.cpp
+++ b/lib/MC/MCStreamer.cpp
@@ -8,7 +8,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCStreamer.h"
-
+#include "llvm/MC/MCExpr.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
MCStreamer::MCStreamer(MCContext &_Context) : Context(_Context), CurSection(0) {
@@ -16,3 +17,25 @@ MCStreamer::MCStreamer(MCContext &_Context) : Context(_Context), CurSection(0) {
MCStreamer::~MCStreamer() {
}
+
+raw_ostream &MCStreamer::GetCommentOS() {
+ // By default, discard comments.
+ return nulls();
+}
+
+
+/// EmitIntValue - Special case of EmitValue that avoids the client having to
+/// pass in a MCExpr for constant integers.
+void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size,
+ unsigned AddrSpace) {
+ EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
+}
+
+/// EmitFill - Emit NumBytes bytes worth of the value specified by
+/// FillValue. This implements directives such as '.space'.
+void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
+ unsigned AddrSpace) {
+ const MCExpr *E = MCConstantExpr::Create(FillValue, getContext());
+ for (uint64_t i = 0, e = NumBytes; i != e; ++i)
+ EmitValue(E, 1, AddrSpace);
+}
diff --git a/lib/MC/MCSymbol.cpp b/lib/MC/MCSymbol.cpp
index 265d06c..3fb1233 100644
--- a/lib/MC/MCSymbol.cpp
+++ b/lib/MC/MCSymbol.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCSymbol.h"
-#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -26,24 +25,11 @@ static bool isAcceptableChar(char C) {
return true;
}
-static char HexDigit(int V) {
- return V < 10 ? V+'0' : V+'A'-10;
-}
-
-static void MangleLetter(raw_ostream &OS, unsigned char C) {
- OS << '_' << HexDigit(C >> 4) << HexDigit(C & 15) << '_';
-}
-
-/// NameNeedsEscaping - Return true if the identifier \arg Str needs quotes
-/// for this assembler.
-static bool NameNeedsEscaping(StringRef Str, const MCAsmInfo &MAI) {
+/// NameNeedsQuoting - Return true if the identifier \arg Str needs quotes to be
+/// syntactically correct.
+static bool NameNeedsQuoting(StringRef Str) {
assert(!Str.empty() && "Cannot create an empty MCSymbol");
- // If the first character is a number and the target does not allow this, we
- // need quotes.
- if (!MAI.doesAllowNameToStartWithDigit() && Str[0] >= '0' && Str[0] <= '9')
- return true;
-
// If any of the characters in the string is an unacceptable character, force
// quotes.
for (unsigned i = 0, e = Str.size(); i != e; ++i)
@@ -52,63 +38,18 @@ static bool NameNeedsEscaping(StringRef Str, const MCAsmInfo &MAI) {
return false;
}
-/// printMangledName - Print the specified string in mangled form if it uses
-/// any unusual characters.
-void MCSymbol::printMangledName(StringRef Str, raw_ostream &OS,
- const MCAsmInfo *MAI) {
- // The first character is not allowed to be a number unless the target
- // explicitly allows it.
- if ((MAI == 0 || !MAI->doesAllowNameToStartWithDigit()) &&
- Str[0] >= '0' && Str[0] <= '9') {
- MangleLetter(OS, Str[0]);
- Str = Str.substr(1);
- }
-
- for (unsigned i = 0, e = Str.size(); i != e; ++i) {
- if (!isAcceptableChar(Str[i]))
- MangleLetter(OS, Str[i]);
- else
- OS << Str[i];
- }
-}
-
-/// PrintMangledQuotedName - On systems that support quoted symbols, we still
-/// have to escape some (obscure) characters like " and \n which would break the
-/// assembler's lexing.
-static void PrintMangledQuotedName(raw_ostream &OS, StringRef Str) {
- OS << '"';
-
- for (unsigned i = 0, e = Str.size(); i != e; ++i) {
- if (Str[i] == '"')
- OS << "_QQ_";
- else if (Str[i] == '\n')
- OS << "_NL_";
- else
- OS << Str[i];
- }
- OS << '"';
-}
-
-
-void MCSymbol::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
- if (MAI == 0 || !NameNeedsEscaping(getName(), *MAI)) {
+void MCSymbol::print(raw_ostream &OS) const {
+ // The name for this MCSymbol is required to be a valid target name. However,
+ // some targets support quoting names with funny characters. If the name
+ // contains a funny character, then print it quoted.
+ if (!NameNeedsQuoting(getName())) {
OS << getName();
return;
}
-
- // On systems that do not allow quoted names, print with mangling.
- if (!MAI->doesAllowQuotesInName())
- return printMangledName(getName(), OS, MAI);
-
- // If the string contains a double quote or newline, we still have to mangle
- // it.
- if (getName().find('"') != std::string::npos ||
- getName().find('\n') != std::string::npos)
- return PrintMangledQuotedName(OS, getName());
OS << '"' << getName() << '"';
}
void MCSymbol::dump() const {
- print(dbgs(), 0);
+ print(dbgs());
}
diff --git a/lib/MC/MCValue.cpp b/lib/MC/MCValue.cpp
index c1222ec..043a49d 100644
--- a/lib/MC/MCValue.cpp
+++ b/lib/MC/MCValue.cpp
@@ -19,12 +19,10 @@ void MCValue::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
return;
}
- getSymA()->print(OS, MAI);
+ OS << *getSymA();
- if (getSymB()) {
- OS << " - ";
- getSymB()->print(OS, MAI);
- }
+ if (getSymB())
+ OS << " - " << *getSymB();
if (getConstant())
OS << " + " << getConstant();
diff --git a/lib/MC/Makefile b/lib/MC/Makefile
index 314a5b1..371776f 100644
--- a/lib/MC/Makefile
+++ b/lib/MC/Makefile
@@ -10,6 +10,8 @@
LEVEL = ../..
LIBRARYNAME = LLVMMC
BUILD_ARCHIVE := 1
+PARALLEL_DIRS := MCParser
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Support/Debug.cpp b/lib/Support/Debug.cpp
index a035771..82b4b8c 100644
--- a/lib/Support/Debug.cpp
+++ b/lib/Support/Debug.cpp
@@ -115,9 +115,9 @@ raw_ostream &llvm::dbgs() {
#else
// Avoid "has no symbols" warning.
namespace llvm {
- /// dbgs - Return dbgs().
+ /// dbgs - Return errs().
raw_ostream &dbgs() {
- return dbgs();
+ return errs();
}
}
diff --git a/lib/Support/SourceMgr.cpp b/lib/Support/SourceMgr.cpp
index 7dd42f4..bdc637a 100644
--- a/lib/Support/SourceMgr.cpp
+++ b/lib/Support/SourceMgr.cpp
@@ -192,18 +192,21 @@ void SMDiagnostic::Print(const char *ProgName, raw_ostream &S) {
if (ProgName && ProgName[0])
S << ProgName << ": ";
- if (Filename == "-")
- S << "<stdin>";
- else
- S << Filename;
+ if (!Filename.empty()) {
+ if (Filename == "-")
+ S << "<stdin>";
+ else
+ S << Filename;
- if (LineNo != -1) {
- S << ':' << LineNo;
- if (ColumnNo != -1)
- S << ':' << (ColumnNo+1);
+ if (LineNo != -1) {
+ S << ':' << LineNo;
+ if (ColumnNo != -1)
+ S << ':' << (ColumnNo+1);
+ }
+ S << ": ";
}
- S << ": " << Message << '\n';
+ S << Message << '\n';
if (LineNo != -1 && ColumnNo != -1 && ShowLine) {
S << LineContents << '\n';
diff --git a/lib/Support/StringExtras.cpp b/lib/Support/StringExtras.cpp
index 785e0ec..eb2fa08 100644
--- a/lib/Support/StringExtras.cpp
+++ b/lib/Support/StringExtras.cpp
@@ -39,13 +39,11 @@ std::pair<StringRef, StringRef> llvm::getToken(StringRef Source,
StringRef Delimiters) {
// Figure out where the token starts.
StringRef::size_type Start = Source.find_first_not_of(Delimiters);
- if (Start == StringRef::npos) Start = Source.size();
// Find the next occurrence of the delimiter.
StringRef::size_type End = Source.find_first_of(Delimiters, Start);
- if (End == StringRef::npos) End = Source.size();
- return std::make_pair(Source.substr(Start, End), Source.substr(End));
+ return std::make_pair(Source.slice(Start, End), Source.substr(End));
}
/// SplitString - Split up the specified string according to the specified
diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp
index a820210..10d7ec0 100644
--- a/lib/Support/raw_ostream.cpp
+++ b/lib/Support/raw_ostream.cpp
@@ -562,6 +562,17 @@ raw_svector_ostream::~raw_svector_ostream() {
flush();
}
+/// resync - This is called when the SmallVector we're appending to is changed
+/// outside of the raw_svector_ostream's control. It is only safe to do this
+/// if the raw_svector_ostream has previously been flushed.
+void raw_svector_ostream::resync() {
+ assert(GetNumBytesInBuffer() == 0 && "Didn't flush before mutating vector");
+
+ if (OS.capacity() - OS.size() < 64)
+ OS.reserve(OS.capacity() * 2);
+ SetBuffer(OS.end(), OS.capacity() - OS.size());
+}
+
void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) {
assert(Ptr == OS.end() && OS.size() + Size <= OS.capacity() &&
"Invalid write_impl() call!");
diff --git a/lib/System/Host.cpp b/lib/System/Host.cpp
index 79897e4..e7193db 100644
--- a/lib/System/Host.cpp
+++ b/lib/System/Host.cpp
@@ -299,3 +299,7 @@ std::string sys::getHostCPUName() {
return "generic";
}
#endif
+
+bool sys::getHostCPUFeatures(StringMap<bool> &Features){
+ return false;
+}
diff --git a/lib/System/Unix/TimeValue.inc b/lib/System/Unix/TimeValue.inc
index 1ae8c71..d8cc8f5 100644
--- a/lib/System/Unix/TimeValue.inc
+++ b/lib/System/Unix/TimeValue.inc
@@ -48,7 +48,7 @@ TimeValue TimeValue::now() {
}
return TimeValue(
- static_cast<TimeValue::SecondsType>( the_time.tv_sec ),
+ static_cast<TimeValue::SecondsType>( the_time.tv_sec + PosixZeroTime.seconds_ ),
static_cast<TimeValue::NanoSecondsType>( the_time.tv_usec *
NANOSECONDS_PER_MICROSECOND ) );
}
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 969c4a4..fd46a4a 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -715,7 +715,7 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
RC == ARM::QPR_VFP2RegisterClass) && "Unknown regclass!");
// FIXME: Neon instructions should support predicates
if (Align >= 16
- && (getRegisterInfo().needsStackRealignment(MF))) {
+ && (getRegisterInfo().canRealignStack(MF))) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VST1q64))
.addFrameIndex(FI).addImm(0).addImm(0).addImm(128)
.addMemOperand(MMO)
@@ -760,7 +760,7 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
RC == ARM::QPR_VFP2RegisterClass ||
RC == ARM::QPR_8RegisterClass) && "Unknown regclass!");
if (Align >= 16
- && (getRegisterInfo().needsStackRealignment(MF))) {
+ && (getRegisterInfo().canRealignStack(MF))) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLD1q64), DestReg)
.addFrameIndex(FI).addImm(0).addImm(0).addImm(128)
.addMemOperand(MMO));
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index f1b6e1d..ba9e044 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -484,6 +484,14 @@ bool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const {
MFI->isFrameAddressTaken());
}
+bool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const {
+ const MachineFrameInfo *MFI = MF.getFrameInfo();
+ const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+ return (RealignStack &&
+ !AFI->isThumb1OnlyFunction() &&
+ !MFI->hasVarSizedObjects());
+}
+
bool ARMBaseRegisterInfo::
needsStackRealignment(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.h b/lib/Target/ARM/ARMBaseRegisterInfo.h
index 2788d07..f5ca25c 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.h
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.h
@@ -96,6 +96,7 @@ public:
bool hasFP(const MachineFunction &MF) const;
+ bool canRealignStack(const MachineFunction &MF) const;
bool needsStackRealignment(const MachineFunction &MF) const;
bool cannotEliminateFrame(const MachineFunction &MF) const;
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 14a45b3..a260050 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -1296,12 +1296,12 @@ SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad,
Ops.push_back(Chain);
if (!IsLoad)
- return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+7);
+ return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+8);
std::vector<EVT> ResTys(NumVecs, RegVT);
ResTys.push_back(MVT::Other);
SDNode *VLdLn =
- CurDAG->getMachineNode(Opc, dl, ResTys, Ops.data(), NumVecs+7);
+ CurDAG->getMachineNode(Opc, dl, ResTys, Ops.data(), NumVecs+8);
// For a 64-bit vector load to D registers, nothing more needs to be done.
if (is64BitVector)
return VLdLn;
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 7b62c00..76c6a27 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -340,7 +340,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
// ARM does not have ROTL.
setOperationAction(ISD::ROTL, MVT::i32, Expand);
- setOperationAction(ISD::CTTZ, MVT::i32, Expand);
+ setOperationAction(ISD::CTTZ, MVT::i32, Custom);
setOperationAction(ISD::CTPOP, MVT::i32, Expand);
if (!Subtarget->hasV5TOps() || Subtarget->isThumb1Only())
setOperationAction(ISD::CTLZ, MVT::i32, Expand);
@@ -387,7 +387,8 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb1Only())
- // Turn f64->i64 into VMOVRRD, i64 -> f64 to VMOVDRR iff target supports vfp2.
+ // Turn f64->i64 into VMOVRRD, i64 -> f64 to VMOVDRR
+ // iff target supports vfp2.
setOperationAction(ISD::BIT_CONVERT, MVT::i64, Custom);
// We want to custom lower some of our intrinsics.
@@ -482,6 +483,8 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
case ARMISD::CMOV: return "ARMISD::CMOV";
case ARMISD::CNEG: return "ARMISD::CNEG";
+ case ARMISD::RBIT: return "ARMISD::RBIT";
+
case ARMISD::FTOSI: return "ARMISD::FTOSI";
case ARMISD::FTOUI: return "ARMISD::FTOUI";
case ARMISD::SITOF: return "ARMISD::SITOF";
@@ -2231,6 +2234,18 @@ SDValue ARMTargetLowering::LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) {
return DAG.getMergeValues(Ops, 2, dl);
}
+static SDValue LowerCTTZ(SDNode *N, SelectionDAG &DAG,
+ const ARMSubtarget *ST) {
+ EVT VT = N->getValueType(0);
+ DebugLoc dl = N->getDebugLoc();
+
+ if (!ST->hasV6T2Ops())
+ return SDValue();
+
+ SDValue rbit = DAG.getNode(ARMISD::RBIT, dl, VT, N->getOperand(0));
+ return DAG.getNode(ISD::CTLZ, dl, VT, rbit);
+}
+
static SDValue LowerShift(SDNode *N, SelectionDAG &DAG,
const ARMSubtarget *ST) {
EVT VT = N->getValueType(0);
@@ -3016,6 +3031,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
case ISD::SHL_PARTS: return LowerShiftLeftParts(Op, DAG);
case ISD::SRL_PARTS:
case ISD::SRA_PARTS: return LowerShiftRightParts(Op, DAG);
+ case ISD::CTTZ: return LowerCTTZ(Op.getNode(), DAG, Subtarget);
case ISD::VSETCC: return LowerVSETCC(Op, DAG);
case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG);
case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG);
@@ -3516,7 +3532,8 @@ static SDValue PerformSUBCombine(SDNode *N,
return SDValue();
}
-/// PerformVMOVRRDCombine - Target-specific dag combine xforms for ARMISD::VMOVRRD.
+/// PerformVMOVRRDCombine - Target-specific dag combine xforms for
+/// ARMISD::VMOVRRD.
static SDValue PerformVMOVRRDCombine(SDNode *N,
TargetLowering::DAGCombinerInfo &DCI) {
// fmrrd(fmdrr x, y) -> x,y
diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h
index e1b3348..cd9c027 100644
--- a/lib/Target/ARM/ARMISelLowering.h
+++ b/lib/Target/ARM/ARMISelLowering.h
@@ -53,6 +53,8 @@ namespace llvm {
CMOV, // ARM conditional move instructions.
CNEG, // ARM conditional negate instructions.
+ RBIT, // ARM bitreverse instruction
+
FTOSI, // FP to sint within a FP register.
FTOUI, // FP to uint within a FP register.
SITOF, // sint to FP within a FP register.
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index f67e74a..af508ee 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -107,6 +107,8 @@ def ARMMemBarrierV6 : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV6,
def ARMSyncBarrierV6 : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERV6,
[SDNPHasChain]>;
+def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
+
//===----------------------------------------------------------------------===//
// ARM Instruction Predicate Definitions.
//
@@ -1455,6 +1457,15 @@ def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
let Inst{19-16} = 0b1111;
}
+def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
+ "rbit", "\t$dst, $src",
+ [(set GPR:$dst, (ARMrbit GPR:$src))]>,
+ Requires<[IsARM, HasV6T2]> {
+ let Inst{7-4} = 0b0011;
+ let Inst{11-8} = 0b1111;
+ let Inst{19-16} = 0b1111;
+}
+
def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
"rev", "\t$dst, $src",
[(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
@@ -1528,8 +1539,10 @@ def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
defm CMP : AI1_cmp_irs<0b1010, "cmp",
BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
-defm CMN : AI1_cmp_irs<0b1011, "cmn",
- BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
+//FIXME: Disable CMN, as CCodes are backwards from compare expectations
+// Compare-to-zero still works out, just not the relationals
+//defm CMN : AI1_cmp_irs<0b1011, "cmn",
+// BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
// Note that TST/TEQ don't set all the same flags that CMP does!
defm TST : AI1_cmp_irs<0b1000, "tst",
@@ -1542,11 +1555,11 @@ defm CMPz : AI1_cmp_irs<0b1010, "cmp",
defm CMNz : AI1_cmp_irs<0b1011, "cmn",
BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
-def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
- (CMNri GPR:$src, so_imm_neg:$imm)>;
+//def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
+// (CMNri GPR:$src, so_imm_neg:$imm)>;
def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
- (CMNri GPR:$src, so_imm_neg:$imm)>;
+ (CMNzri GPR:$src, so_imm_neg:$imm)>;
// Conditional moves
diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td
index 61b7705..cd063bf 100644
--- a/lib/Target/ARM/ARMInstrNEON.td
+++ b/lib/Target/ARM/ARMInstrNEON.td
@@ -197,12 +197,12 @@ let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
class VLD2D<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b10,0b1000,op7_4, (outs DPR:$dst1, DPR:$dst2),
(ins addrmode6:$addr), IIC_VLD2,
- OpcodeStr, Dt, "\\{$dst1,$dst2\\}, $addr", "", []>;
+ OpcodeStr, Dt, "\\{$dst1, $dst2\\}, $addr", "", []>;
class VLD2Q<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b10,0b0011,op7_4,
(outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4),
(ins addrmode6:$addr), IIC_VLD2,
- OpcodeStr, Dt, "\\{$dst1,$dst2,$dst3,$dst4\\}, $addr",
+ OpcodeStr, Dt, "\\{$dst1, $dst2, $dst3, $dst4\\}, $addr",
"", []>;
def VLD2d8 : VLD2D<0b0000, "vld2", "8">;
@@ -210,7 +210,7 @@ def VLD2d16 : VLD2D<0b0100, "vld2", "16">;
def VLD2d32 : VLD2D<0b1000, "vld2", "32">;
def VLD2d64 : NLdSt<0,0b10,0b1010,0b1100, (outs DPR:$dst1, DPR:$dst2),
(ins addrmode6:$addr), IIC_VLD1,
- "vld1", "64", "\\{$dst1,$dst2\\}, $addr", "", []>;
+ "vld1", "64", "\\{$dst1, $dst2\\}, $addr", "", []>;
def VLD2q8 : VLD2Q<0b0000, "vld2", "8">;
def VLD2q16 : VLD2Q<0b0100, "vld2", "16">;
@@ -220,11 +220,11 @@ def VLD2q32 : VLD2Q<0b1000, "vld2", "32">;
class VLD3D<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b10,0b0100,op7_4, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3),
(ins addrmode6:$addr), IIC_VLD3,
- OpcodeStr, Dt, "\\{$dst1,$dst2,$dst3\\}, $addr", "", []>;
+ OpcodeStr, Dt, "\\{$dst1, $dst2, $dst3\\}, $addr", "", []>;
class VLD3WB<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b10,0b0101,op7_4, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3, GPR:$wb),
(ins addrmode6:$addr), IIC_VLD3,
- OpcodeStr, Dt, "\\{$dst1,$dst2,$dst3\\}, $addr",
+ OpcodeStr, Dt, "\\{$dst1, $dst2, $dst3\\}, $addr",
"$addr.addr = $wb", []>;
def VLD3d8 : VLD3D<0b0000, "vld3", "8">;
@@ -233,7 +233,7 @@ def VLD3d32 : VLD3D<0b1000, "vld3", "32">;
def VLD3d64 : NLdSt<0,0b10,0b0110,0b1100,
(outs DPR:$dst1, DPR:$dst2, DPR:$dst3),
(ins addrmode6:$addr), IIC_VLD1,
- "vld1", "64", "\\{$dst1,$dst2,$dst3\\}, $addr", "", []>;
+ "vld1", "64", "\\{$dst1, $dst2, $dst3\\}, $addr", "", []>;
// vld3 to double-spaced even registers.
def VLD3q8a : VLD3WB<0b0000, "vld3", "8">;
@@ -250,13 +250,13 @@ class VLD4D<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b10,0b0000,op7_4,
(outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4),
(ins addrmode6:$addr), IIC_VLD4,
- OpcodeStr, Dt, "\\{$dst1,$dst2,$dst3,$dst4\\}, $addr",
+ OpcodeStr, Dt, "\\{$dst1, $dst2, $dst3, $dst4\\}, $addr",
"", []>;
class VLD4WB<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b10,0b0001,op7_4,
(outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb),
(ins addrmode6:$addr), IIC_VLD4,
- OpcodeStr, Dt, "\\{$dst1,$dst2,$dst3,$dst4\\}, $addr",
+ OpcodeStr, Dt, "\\{$dst1, $dst2, $dst3, $dst4\\}, $addr",
"$addr.addr = $wb", []>;
def VLD4d8 : VLD4D<0b0000, "vld4", "8">;
@@ -265,7 +265,8 @@ def VLD4d32 : VLD4D<0b1000, "vld4", "32">;
def VLD4d64 : NLdSt<0,0b10,0b0010,0b1100,
(outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4),
(ins addrmode6:$addr), IIC_VLD1,
- "vld1", "64", "\\{$dst1,$dst2,$dst3,$dst4\\}, $addr", "", []>;
+ "vld1", "64", "\\{$dst1, $dst2, $dst3, $dst4\\}, $addr",
+ "", []>;
// vld4 to double-spaced even registers.
def VLD4q8a : VLD4WB<0b0000, "vld4", "8">;
@@ -285,7 +286,7 @@ class VLD2LN<bits<4> op11_8, string OpcodeStr, string Dt>
: NLdSt<1,0b10,op11_8,{?,?,?,?}, (outs DPR:$dst1, DPR:$dst2),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, nohash_imm:$lane),
IIC_VLD2,
- OpcodeStr, Dt, "\\{$dst1[$lane],$dst2[$lane]\\}, $addr",
+ OpcodeStr, Dt, "\\{$dst1[$lane], $dst2[$lane]\\}, $addr",
"$src1 = $dst1, $src2 = $dst2", []>;
// vld2 to single-spaced registers.
@@ -319,7 +320,7 @@ class VLD3LN<bits<4> op11_8, string OpcodeStr, string Dt>
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3,
nohash_imm:$lane), IIC_VLD3,
OpcodeStr, Dt,
- "\\{$dst1[$lane],$dst2[$lane],$dst3[$lane]\\}, $addr",
+ "\\{$dst1[$lane], $dst2[$lane], $dst3[$lane]\\}, $addr",
"$src1 = $dst1, $src2 = $dst2, $src3 = $dst3", []>;
// vld3 to single-spaced registers.
@@ -356,7 +357,7 @@ class VLD4LN<bits<4> op11_8, string OpcodeStr, string Dt>
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4,
nohash_imm:$lane), IIC_VLD4,
OpcodeStr, Dt,
- "\\{$dst1[$lane],$dst2[$lane],$dst3[$lane],$dst4[$lane]\\}, $addr",
+ "\\{$dst1[$lane], $dst2[$lane], $dst3[$lane], $dst4[$lane]\\}, $addr",
"$src1 = $dst1, $src2 = $dst2, $src3 = $dst3, $src4 = $dst4", []>;
// vld4 to single-spaced registers.
@@ -423,12 +424,12 @@ let mayStore = 1, hasExtraSrcRegAllocReq = 1 in {
class VST2D<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b00,0b1000,op7_4, (outs),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2), IIC_VST,
- OpcodeStr, Dt, "\\{$src1,$src2\\}, $addr", "", []>;
+ OpcodeStr, Dt, "\\{$src1, $src2\\}, $addr", "", []>;
class VST2Q<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b00,0b0011,op7_4, (outs),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4),
IIC_VST,
- OpcodeStr, Dt, "\\{$src1,$src2,$src3,$src4\\}, $addr",
+ OpcodeStr, Dt, "\\{$src1, $src2, $src3, $src4\\}, $addr",
"", []>;
def VST2d8 : VST2D<0b0000, "vst2", "8">;
@@ -436,7 +437,7 @@ def VST2d16 : VST2D<0b0100, "vst2", "16">;
def VST2d32 : VST2D<0b1000, "vst2", "32">;
def VST2d64 : NLdSt<0,0b00,0b1010,0b1100, (outs),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2), IIC_VST,
- "vst1", "64", "\\{$src1,$src2\\}, $addr", "", []>;
+ "vst1", "64", "\\{$src1, $src2\\}, $addr", "", []>;
def VST2q8 : VST2Q<0b0000, "vst2", "8">;
def VST2q16 : VST2Q<0b0100, "vst2", "16">;
@@ -446,11 +447,11 @@ def VST2q32 : VST2Q<0b1000, "vst2", "32">;
class VST3D<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b00,0b0100,op7_4, (outs),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3), IIC_VST,
- OpcodeStr, Dt, "\\{$src1,$src2,$src3\\}, $addr", "", []>;
+ OpcodeStr, Dt, "\\{$src1, $src2, $src3\\}, $addr", "", []>;
class VST3WB<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b00,0b0101,op7_4, (outs GPR:$wb),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3), IIC_VST,
- OpcodeStr, Dt, "\\{$src1,$src2,$src3\\}, $addr",
+ OpcodeStr, Dt, "\\{$src1, $src2, $src3\\}, $addr",
"$addr.addr = $wb", []>;
def VST3d8 : VST3D<0b0000, "vst3", "8">;
@@ -459,7 +460,7 @@ def VST3d32 : VST3D<0b1000, "vst3", "32">;
def VST3d64 : NLdSt<0,0b00,0b0110,0b1100, (outs),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3),
IIC_VST,
- "vst1", "64", "\\{$src1,$src2,$src3\\}, $addr", "", []>;
+ "vst1", "64", "\\{$src1, $src2, $src3\\}, $addr", "", []>;
// vst3 to double-spaced even registers.
def VST3q8a : VST3WB<0b0000, "vst3", "8">;
@@ -476,13 +477,13 @@ class VST4D<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b00,0b0000,op7_4, (outs),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4),
IIC_VST,
- OpcodeStr, Dt, "\\{$src1,$src2,$src3,$src4\\}, $addr",
+ OpcodeStr, Dt, "\\{$src1, $src2, $src3, $src4\\}, $addr",
"", []>;
class VST4WB<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b00,0b0001,op7_4, (outs GPR:$wb),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4),
IIC_VST,
- OpcodeStr, Dt, "\\{$src1,$src2,$src3,$src4\\}, $addr",
+ OpcodeStr, Dt, "\\{$src1, $src2, $src3, $src4\\}, $addr",
"$addr.addr = $wb", []>;
def VST4d8 : VST4D<0b0000, "vst4", "8">;
@@ -491,7 +492,8 @@ def VST4d32 : VST4D<0b1000, "vst4", "32">;
def VST4d64 : NLdSt<0,0b00,0b0010,0b1100, (outs),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3,
DPR:$src4), IIC_VST,
- "vst1", "64", "\\{$src1,$src2,$src3,$src4\\}, $addr", "", []>;
+ "vst1", "64", "\\{$src1, $src2, $src3, $src4\\}, $addr",
+ "", []>;
// vst4 to double-spaced even registers.
def VST4q8a : VST4WB<0b0000, "vst4", "8">;
@@ -511,7 +513,7 @@ class VST2LN<bits<4> op11_8, string OpcodeStr, string Dt>
: NLdSt<1,0b00,op11_8,{?,?,?,?}, (outs),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, nohash_imm:$lane),
IIC_VST,
- OpcodeStr, Dt, "\\{$src1[$lane],$src2[$lane]\\}, $addr",
+ OpcodeStr, Dt, "\\{$src1[$lane], $src2[$lane]\\}, $addr",
"", []>;
// vst2 to single-spaced registers.
@@ -545,7 +547,7 @@ class VST3LN<bits<4> op11_8, string OpcodeStr, string Dt>
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3,
nohash_imm:$lane), IIC_VST,
OpcodeStr, Dt,
- "\\{$src1[$lane],$src2[$lane],$src3[$lane]\\}, $addr", "", []>;
+ "\\{$src1[$lane], $src2[$lane], $src3[$lane]\\}, $addr", "", []>;
// vst3 to single-spaced registers.
def VST3LNd8 : VST3LN<0b0010, "vst3", "8"> {
@@ -580,7 +582,7 @@ class VST4LN<bits<4> op11_8, string OpcodeStr, string Dt>
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4,
nohash_imm:$lane), IIC_VST,
OpcodeStr, Dt,
- "\\{$src1[$lane],$src2[$lane],$src3[$lane],$src4[$lane]\\}, $addr",
+ "\\{$src1[$lane], $src2[$lane], $src3[$lane], $src4[$lane]\\}, $addr",
"", []>;
// vst4 to single-spaced registers.
@@ -2116,7 +2118,7 @@ def VACGTq : N3VQInt<1, 0, 0b10, 0b1110, 1, IIC_VBINQ, "vacgt", "f32",
v4i32, v4f32, int_arm_neon_vacgtq, 0>;
// VTST : Vector Test Bits
defm VTST : N3V_QHS<0, 0, 0b1000, 1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
- IIC_VBINi4Q, "vtst", "i", NEONvtst, 1>;
+ IIC_VBINi4Q, "vtst", "", NEONvtst, 1>;
// Vector Bitwise Operations.
@@ -3022,19 +3024,19 @@ let hasExtraSrcRegAllocReq = 1 in {
def VTBL2
: N3V<1,1,0b11,0b1001,0,0, (outs DPR:$dst),
(ins DPR:$tbl1, DPR:$tbl2, DPR:$src), IIC_VTB2,
- "vtbl", "8", "$dst, \\{$tbl1,$tbl2\\}, $src", "",
+ "vtbl", "8", "$dst, \\{$tbl1, $tbl2\\}, $src", "",
[(set DPR:$dst, (v8i8 (int_arm_neon_vtbl2
DPR:$tbl1, DPR:$tbl2, DPR:$src)))]>;
def VTBL3
: N3V<1,1,0b11,0b1010,0,0, (outs DPR:$dst),
(ins DPR:$tbl1, DPR:$tbl2, DPR:$tbl3, DPR:$src), IIC_VTB3,
- "vtbl", "8", "$dst, \\{$tbl1,$tbl2,$tbl3\\}, $src", "",
+ "vtbl", "8", "$dst, \\{$tbl1, $tbl2, $tbl3\\}, $src", "",
[(set DPR:$dst, (v8i8 (int_arm_neon_vtbl3
DPR:$tbl1, DPR:$tbl2, DPR:$tbl3, DPR:$src)))]>;
def VTBL4
: N3V<1,1,0b11,0b1011,0,0, (outs DPR:$dst),
(ins DPR:$tbl1, DPR:$tbl2, DPR:$tbl3, DPR:$tbl4, DPR:$src), IIC_VTB4,
- "vtbl", "8", "$dst, \\{$tbl1,$tbl2,$tbl3,$tbl4\\}, $src", "",
+ "vtbl", "8", "$dst, \\{$tbl1, $tbl2, $tbl3, $tbl4\\}, $src", "",
[(set DPR:$dst, (v8i8 (int_arm_neon_vtbl4 DPR:$tbl1, DPR:$tbl2,
DPR:$tbl3, DPR:$tbl4, DPR:$src)))]>;
} // hasExtraSrcRegAllocReq = 1
@@ -3050,19 +3052,20 @@ let hasExtraSrcRegAllocReq = 1 in {
def VTBX2
: N3V<1,1,0b11,0b1001,1,0, (outs DPR:$dst),
(ins DPR:$orig, DPR:$tbl1, DPR:$tbl2, DPR:$src), IIC_VTBX2,
- "vtbx", "8", "$dst, \\{$tbl1,$tbl2\\}, $src", "$orig = $dst",
+ "vtbx", "8", "$dst, \\{$tbl1, $tbl2\\}, $src", "$orig = $dst",
[(set DPR:$dst, (v8i8 (int_arm_neon_vtbx2
DPR:$orig, DPR:$tbl1, DPR:$tbl2, DPR:$src)))]>;
def VTBX3
: N3V<1,1,0b11,0b1010,1,0, (outs DPR:$dst),
(ins DPR:$orig, DPR:$tbl1, DPR:$tbl2, DPR:$tbl3, DPR:$src), IIC_VTBX3,
- "vtbx", "8", "$dst, \\{$tbl1,$tbl2,$tbl3\\}, $src", "$orig = $dst",
+ "vtbx", "8", "$dst, \\{$tbl1, $tbl2, $tbl3\\}, $src", "$orig = $dst",
[(set DPR:$dst, (v8i8 (int_arm_neon_vtbx3 DPR:$orig, DPR:$tbl1,
DPR:$tbl2, DPR:$tbl3, DPR:$src)))]>;
def VTBX4
: N3V<1,1,0b11,0b1011,1,0, (outs DPR:$dst), (ins DPR:$orig, DPR:$tbl1,
DPR:$tbl2, DPR:$tbl3, DPR:$tbl4, DPR:$src), IIC_VTBX4,
- "vtbx", "8", "$dst, \\{$tbl1,$tbl2,$tbl3,$tbl4\\}, $src", "$orig = $dst",
+ "vtbx", "8", "$dst, \\{$tbl1, $tbl2, $tbl3, $tbl4\\}, $src",
+ "$orig = $dst",
[(set DPR:$dst, (v8i8 (int_arm_neon_vtbx4 DPR:$orig, DPR:$tbl1,
DPR:$tbl2, DPR:$tbl3, DPR:$tbl4, DPR:$src)))]>;
} // hasExtraSrcRegAllocReq = 1
diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td
index 603ccf5..746caff 100644
--- a/lib/Target/ARM/ARMInstrThumb.td
+++ b/lib/Target/ARM/ARMInstrThumb.td
@@ -208,7 +208,7 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
def tBRIND : TI<(outs), (ins GPR:$dst), IIC_Br, "mov\tpc, $dst",
[(brind GPR:$dst)]>,
- T1Special<{1,0,1,1}> {
+ T1Special<{1,0,1,?}> {
// <Rd> = Inst{7:2-0} = pc
let Inst{2-0} = 0b111;
}
@@ -534,10 +534,12 @@ def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
// CMN register
let Defs = [CPSR] in {
-def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
- "cmn", "\t$lhs, $rhs",
- [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>,
- T1DataProcessing<0b1011>;
+//FIXME: Disable CMN, as CCodes are backwards from compare expectations
+// Compare-to-zero still works out, just not the relationals
+//def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
+// "cmn", "\t$lhs, $rhs",
+// [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>,
+// T1DataProcessing<0b1011>;
def tCMNz : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
"cmn", "\t$lhs, $rhs",
[(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>,
@@ -630,13 +632,13 @@ def tMOVSr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr,
// FIXME: Make these predicable.
def tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src), IIC_iMOVr,
"mov\t$dst, $src", []>,
- T1Special<{1,0,0,1}>;
+ T1Special<{1,0,0,?}>;
def tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src), IIC_iMOVr,
"mov\t$dst, $src", []>,
- T1Special<{1,0,1,0}>;
+ T1Special<{1,0,?,0}>;
def tMOVgpr2gpr : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
"mov\t$dst, $src", []>,
- T1Special<{1,0,1,1}>;
+ T1Special<{1,0,?,?}>;
} // neverHasSideEffects
// multiply register
@@ -771,7 +773,7 @@ let usesCustomInserter = 1 in // Expanded after instruction selection.
// 16-bit movcc in IT blocks for Thumb2.
def tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iCMOVr,
"mov", "\t$dst, $rhs", []>,
- T1Special<{1,0,1,1}>;
+ T1Special<{1,0,?,?}>;
def tMOVCCi : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iCMOVi,
"mov", "\t$dst, $rhs", []>,
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index 769df7e..c7591d2 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -1540,6 +1540,10 @@ class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops, InstrItinClass itin
def t2CLZ : T2I_misc<0b11, 0b00, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
"clz", "\t$dst, $src", [(set GPR:$dst, (ctlz GPR:$src))]>;
+def t2RBIT : T2I_misc<0b01, 0b10, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
+ "rbit", "\t$dst, $src",
+ [(set GPR:$dst, (ARMrbit GPR:$src))]>;
+
def t2REV : T2I_misc<0b01, 0b00, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
"rev", ".w\t$dst, $src", [(set GPR:$dst, (bswap GPR:$src))]>;
@@ -1605,16 +1609,18 @@ defm t2CMP : T2I_cmp_irs<0b1101, "cmp",
defm t2CMPz : T2I_cmp_irs<0b1101, "cmp",
BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
-defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
- BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
+//FIXME: Disable CMN, as CCodes are backwards from compare expectations
+// Compare-to-zero still works out, just not the relationals
+//defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
+// BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
-def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
- (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
+//def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
+// (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
- (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
+ (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
defm t2TST : T2I_cmp_irs<0b0000, "tst",
BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
diff --git a/lib/Target/ARM/ARMMCAsmInfo.cpp b/lib/Target/ARM/ARMMCAsmInfo.cpp
index 0ff65d2..3dd87c0 100644
--- a/lib/Target/ARM/ARMMCAsmInfo.cpp
+++ b/lib/Target/ARM/ARMMCAsmInfo.cpp
@@ -64,7 +64,7 @@ ARMELFMCAsmInfo::ARMELFMCAsmInfo() {
PrivateGlobalPrefix = ".L";
WeakRefDirective = "\t.weak\t";
SetDirective = "\t.set\t";
- LCOMMDirective = "\t.lcomm\t";
+ HasLCOMMDirective = true;
DwarfRequiresFrameSection = false;
diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp
index 1c6fca7..4d20a5c 100644
--- a/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/lib/Target/ARM/ARMTargetMachine.cpp
@@ -93,10 +93,6 @@ bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM,
if (Subtarget.hasNEON())
PM.add(createNEONPreAllocPass());
- // Calculate and set max stack object alignment early, so we can decide
- // whether we will need stack realignment (and thus FP).
- PM.add(createMaxStackAlignmentCalculatorPass());
-
// FIXME: temporarily disabling load / store optimization pass for Thumb1.
if (OptLevel != CodeGenOpt::None && !Subtarget.isThumb1Only())
PM.add(createARMLoadStoreOptimizationPass(true));
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 132738e..89c7769 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -8,18 +8,18 @@
//===----------------------------------------------------------------------===//
#include "ARM.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/MC/MCAsmLexer.h"
-#include "llvm/MC/MCAsmParser.h"
-#include "llvm/MC/MCParsedAsmOperand.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/SourceMgr.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetAsmParser.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Twine.h"
using namespace llvm;
namespace {
@@ -222,7 +222,7 @@ struct ARMOperand : public MCParsedAsmOperand {
/// TODO this is likely to change to allow different register types and or to
/// parse for a specific register type.
bool ARMAsmParser::MaybeParseRegister(ARMOperand &Op, bool ParseWriteBack) {
- const AsmToken &Tok = getLexer().getTok();
+ const AsmToken &Tok = Parser.getTok();
assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
// FIXME: Validate register for the current architecture; we have to do
@@ -232,14 +232,14 @@ bool ARMAsmParser::MaybeParseRegister(ARMOperand &Op, bool ParseWriteBack) {
RegNum = MatchRegisterName(Tok.getString());
if (RegNum == -1)
return true;
- getLexer().Lex(); // Eat identifier token.
+ Parser.Lex(); // Eat identifier token.
bool Writeback = false;
if (ParseWriteBack) {
- const AsmToken &ExclaimTok = getLexer().getTok();
+ const AsmToken &ExclaimTok = Parser.getTok();
if (ExclaimTok.is(AsmToken::Exclaim)) {
Writeback = true;
- getLexer().Lex(); // Eat exclaim token
+ Parser.Lex(); // Eat exclaim token
}
}
@@ -251,26 +251,26 @@ bool ARMAsmParser::MaybeParseRegister(ARMOperand &Op, bool ParseWriteBack) {
/// Parse a register list, return false if successful else return true or an
/// error. The first token must be a '{' when called.
bool ARMAsmParser::ParseRegisterList(ARMOperand &Op) {
- assert(getLexer().getTok().is(AsmToken::LCurly) &&
+ assert(Parser.getTok().is(AsmToken::LCurly) &&
"Token is not an Left Curly Brace");
- getLexer().Lex(); // Eat left curly brace token.
+ Parser.Lex(); // Eat left curly brace token.
- const AsmToken &RegTok = getLexer().getTok();
+ const AsmToken &RegTok = Parser.getTok();
SMLoc RegLoc = RegTok.getLoc();
if (RegTok.isNot(AsmToken::Identifier))
return Error(RegLoc, "register expected");
int RegNum = MatchRegisterName(RegTok.getString());
if (RegNum == -1)
return Error(RegLoc, "register expected");
- getLexer().Lex(); // Eat identifier token.
+ Parser.Lex(); // Eat identifier token.
unsigned RegList = 1 << RegNum;
int HighRegNum = RegNum;
// TODO ranges like "{Rn-Rm}"
- while (getLexer().getTok().is(AsmToken::Comma)) {
- getLexer().Lex(); // Eat comma token.
+ while (Parser.getTok().is(AsmToken::Comma)) {
+ Parser.Lex(); // Eat comma token.
- const AsmToken &RegTok = getLexer().getTok();
+ const AsmToken &RegTok = Parser.getTok();
SMLoc RegLoc = RegTok.getLoc();
if (RegTok.isNot(AsmToken::Identifier))
return Error(RegLoc, "register expected");
@@ -285,12 +285,12 @@ bool ARMAsmParser::ParseRegisterList(ARMOperand &Op) {
RegList |= 1 << RegNum;
HighRegNum = RegNum;
- getLexer().Lex(); // Eat identifier token.
+ Parser.Lex(); // Eat identifier token.
}
- const AsmToken &RCurlyTok = getLexer().getTok();
+ const AsmToken &RCurlyTok = Parser.getTok();
if (RCurlyTok.isNot(AsmToken::RCurly))
return Error(RCurlyTok.getLoc(), "'}' expected");
- getLexer().Lex(); // Eat left curly brace token.
+ Parser.Lex(); // Eat left curly brace token.
return false;
}
@@ -300,11 +300,11 @@ bool ARMAsmParser::ParseRegisterList(ARMOperand &Op) {
/// TODO Only preindexing and postindexing addressing are started, unindexed
/// with option, etc are still to do.
bool ARMAsmParser::ParseMemory(ARMOperand &Op) {
- assert(getLexer().getTok().is(AsmToken::LBrac) &&
+ assert(Parser.getTok().is(AsmToken::LBrac) &&
"Token is not an Left Bracket");
- getLexer().Lex(); // Eat left bracket token.
+ Parser.Lex(); // Eat left bracket token.
- const AsmToken &BaseRegTok = getLexer().getTok();
+ const AsmToken &BaseRegTok = Parser.getTok();
if (BaseRegTok.isNot(AsmToken::Identifier))
return Error(BaseRegTok.getLoc(), "register expected");
if (MaybeParseRegister(Op, false))
@@ -319,10 +319,10 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) {
// First look for preindexed address forms, that is after the "[Rn" we now
// have to see if the next token is a comma.
- const AsmToken &Tok = getLexer().getTok();
+ const AsmToken &Tok = Parser.getTok();
if (Tok.is(AsmToken::Comma)) {
Preindexed = true;
- getLexer().Lex(); // Eat comma token.
+ Parser.Lex(); // Eat comma token.
int OffsetRegNum;
bool OffsetRegShifted;
enum ShiftType ShiftType;
@@ -331,15 +331,15 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) {
if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
Offset, OffsetIsReg, OffsetRegNum))
return true;
- const AsmToken &RBracTok = getLexer().getTok();
+ const AsmToken &RBracTok = Parser.getTok();
if (RBracTok.isNot(AsmToken::RBrac))
return Error(RBracTok.getLoc(), "']' expected");
- getLexer().Lex(); // Eat right bracket token.
+ Parser.Lex(); // Eat right bracket token.
- const AsmToken &ExclaimTok = getLexer().getTok();
+ const AsmToken &ExclaimTok = Parser.getTok();
if (ExclaimTok.is(AsmToken::Exclaim)) {
Writeback = true;
- getLexer().Lex(); // Eat exclaim token
+ Parser.Lex(); // Eat exclaim token
}
Op = ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum,
OffsetRegShifted, ShiftType, ShiftAmount,
@@ -352,7 +352,7 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) {
// the "[Rn".
Postindexed = true;
Writeback = true;
- getLexer().Lex(); // Eat right bracket token.
+ Parser.Lex(); // Eat right bracket token.
int OffsetRegNum = 0;
bool OffsetRegShifted = false;
@@ -360,11 +360,11 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) {
const MCExpr *ShiftAmount;
const MCExpr *Offset;
- const AsmToken &NextTok = getLexer().getTok();
+ const AsmToken &NextTok = Parser.getTok();
if (NextTok.isNot(AsmToken::EndOfStatement)) {
if (NextTok.isNot(AsmToken::Comma))
return Error(NextTok.getLoc(), "',' expected");
- getLexer().Lex(); // Eat comma token.
+ Parser.Lex(); // Eat comma token.
if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
ShiftAmount, Offset, OffsetIsReg, OffsetRegNum))
return true;
@@ -398,15 +398,15 @@ bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
OffsetRegShifted = false;
OffsetIsReg = false;
OffsetRegNum = -1;
- const AsmToken &NextTok = getLexer().getTok();
+ const AsmToken &NextTok = Parser.getTok();
if (NextTok.is(AsmToken::Plus))
- getLexer().Lex(); // Eat plus token.
+ Parser.Lex(); // Eat plus token.
else if (NextTok.is(AsmToken::Minus)) {
Negative = true;
- getLexer().Lex(); // Eat minus token
+ Parser.Lex(); // Eat minus token
}
// See if there is a register following the "[Rn," or "[Rn]," we have so far.
- const AsmToken &OffsetRegTok = getLexer().getTok();
+ const AsmToken &OffsetRegTok = Parser.getTok();
if (OffsetRegTok.is(AsmToken::Identifier)) {
OffsetIsReg = !MaybeParseRegister(Op, false);
if (OffsetIsReg)
@@ -415,11 +415,11 @@ bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
// If we parsed a register as the offset then their can be a shift after that
if (OffsetRegNum != -1) {
// Look for a comma then a shift
- const AsmToken &Tok = getLexer().getTok();
+ const AsmToken &Tok = Parser.getTok();
if (Tok.is(AsmToken::Comma)) {
- getLexer().Lex(); // Eat comma token.
+ Parser.Lex(); // Eat comma token.
- const AsmToken &Tok = getLexer().getTok();
+ const AsmToken &Tok = Parser.getTok();
if (ParseShift(ShiftType, ShiftAmount))
return Error(Tok.getLoc(), "shift expected");
OffsetRegShifted = true;
@@ -427,10 +427,10 @@ bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
}
else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm"
// Look for #offset following the "[Rn," or "[Rn],"
- const AsmToken &HashTok = getLexer().getTok();
+ const AsmToken &HashTok = Parser.getTok();
if (HashTok.isNot(AsmToken::Hash))
return Error(HashTok.getLoc(), "'#' expected");
- getLexer().Lex(); // Eat hash token.
+ Parser.Lex(); // Eat hash token.
if (getParser().ParseExpression(Offset))
return true;
@@ -443,7 +443,7 @@ bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
/// rrx
/// and returns true if it parses a shift otherwise it returns false.
bool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount) {
- const AsmToken &Tok = getLexer().getTok();
+ const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Identifier))
return true;
const StringRef &ShiftName = Tok.getString();
@@ -459,17 +459,17 @@ bool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount) {
St = Rrx;
else
return true;
- getLexer().Lex(); // Eat shift type token.
+ Parser.Lex(); // Eat shift type token.
// Rrx stands alone.
if (St == Rrx)
return false;
// Otherwise, there must be a '#' and a shift amount.
- const AsmToken &HashTok = getLexer().getTok();
+ const AsmToken &HashTok = Parser.getTok();
if (HashTok.isNot(AsmToken::Hash))
return Error(HashTok.getLoc(), "'#' expected");
- getLexer().Lex(); // Eat hash token.
+ Parser.Lex(); // Eat hash token.
if (getParser().ParseExpression(ShiftAmount))
return true;
@@ -569,14 +569,14 @@ bool ARMAsmParser::ParseOperand(ARMOperand &Op) {
case AsmToken::Hash:
// #42 -> immediate.
// TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
- getLexer().Lex();
+ Parser.Lex();
const MCExpr *ImmVal;
if (getParser().ParseExpression(ImmVal))
return true;
Op = ARMOperand::CreateImm(ImmVal);
return false;
default:
- return Error(getLexer().getTok().getLoc(), "unexpected token in operand");
+ return Error(Parser.getTok().getLoc(), "unexpected token in operand");
}
}
@@ -585,7 +585,7 @@ bool ARMAsmParser::ParseInstruction(const StringRef &Name, SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Operands.push_back(new ARMOperand(ARMOperand::CreateToken(Name)));
- SMLoc Loc = getLexer().getTok().getLoc();
+ SMLoc Loc = Parser.getTok().getLoc();
if (getLexer().isNot(AsmToken::EndOfStatement)) {
// Read the first operand.
@@ -594,7 +594,7 @@ bool ARMAsmParser::ParseInstruction(const StringRef &Name, SMLoc NameLoc,
Operands.push_back(new ARMOperand(Op));
while (getLexer().is(AsmToken::Comma)) {
- getLexer().Lex(); // Eat the comma.
+ Parser.Lex(); // Eat the comma.
// Parse and remember the operand.
if (ParseOperand(Op)) return true;
@@ -629,7 +629,7 @@ bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
if (getParser().ParseExpression(Value))
return true;
- getParser().getStreamer().EmitValue(Value, Size);
+ getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
if (getLexer().is(AsmToken::EndOfStatement))
break;
@@ -637,11 +637,11 @@ bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
// FIXME: Improve diagnostic.
if (getLexer().isNot(AsmToken::Comma))
return Error(L, "unexpected token in directive");
- getLexer().Lex();
+ Parser.Lex();
}
}
- getLexer().Lex();
+ Parser.Lex();
return false;
}
@@ -650,7 +650,7 @@ bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
bool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return Error(L, "unexpected token in directive");
- getLexer().Lex();
+ Parser.Lex();
// TODO: set thumb mode
// TODO: tell the MC streamer the mode
@@ -661,15 +661,15 @@ bool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
/// ParseDirectiveThumbFunc
/// ::= .thumbfunc symbol_name
bool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
- const AsmToken &Tok = getLexer().getTok();
+ const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
return Error(L, "unexpected token in .syntax directive");
- StringRef ATTRIBUTE_UNUSED SymbolName = getLexer().getTok().getIdentifier();
- getLexer().Lex(); // Consume the identifier token.
+ StringRef ATTRIBUTE_UNUSED SymbolName = Parser.getTok().getIdentifier();
+ Parser.Lex(); // Consume the identifier token.
if (getLexer().isNot(AsmToken::EndOfStatement))
return Error(L, "unexpected token in directive");
- getLexer().Lex();
+ Parser.Lex();
// TODO: mark symbol as a thumb symbol
// getParser().getStreamer().Emit???();
@@ -679,25 +679,25 @@ bool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
/// ParseDirectiveSyntax
/// ::= .syntax unified | divided
bool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) {
- const AsmToken &Tok = getLexer().getTok();
+ const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Identifier))
return Error(L, "unexpected token in .syntax directive");
const StringRef &Mode = Tok.getString();
bool unified_syntax;
if (Mode == "unified" || Mode == "UNIFIED") {
- getLexer().Lex();
+ Parser.Lex();
unified_syntax = true;
}
else if (Mode == "divided" || Mode == "DIVIDED") {
- getLexer().Lex();
+ Parser.Lex();
unified_syntax = false;
}
else
return Error(L, "unrecognized syntax mode in .syntax directive");
if (getLexer().isNot(AsmToken::EndOfStatement))
- return Error(getLexer().getTok().getLoc(), "unexpected token in directive");
- getLexer().Lex();
+ return Error(Parser.getTok().getLoc(), "unexpected token in directive");
+ Parser.Lex();
// TODO tell the MC streamer the mode
// getParser().getStreamer().Emit???();
@@ -707,25 +707,25 @@ bool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) {
/// ParseDirectiveCode
/// ::= .code 16 | 32
bool ARMAsmParser::ParseDirectiveCode(SMLoc L) {
- const AsmToken &Tok = getLexer().getTok();
+ const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Integer))
return Error(L, "unexpected token in .code directive");
- int64_t Val = getLexer().getTok().getIntVal();
+ int64_t Val = Parser.getTok().getIntVal();
bool thumb_mode;
if (Val == 16) {
- getLexer().Lex();
+ Parser.Lex();
thumb_mode = true;
}
else if (Val == 32) {
- getLexer().Lex();
+ Parser.Lex();
thumb_mode = false;
}
else
return Error(L, "invalid operand to .code directive");
if (getLexer().isNot(AsmToken::EndOfStatement))
- return Error(getLexer().getTok().getLoc(), "unexpected token in directive");
- getLexer().Lex();
+ return Error(Parser.getTok().getLoc(), "unexpected token in directive");
+ Parser.Lex();
// TODO tell the MC streamer the mode
// getParser().getStreamer().Emit???();
diff --git a/lib/Target/ARM/AsmParser/Makefile b/lib/Target/ARM/AsmParser/Makefile
index 97e5612..4fb8564 100644
--- a/lib/Target/ARM/AsmParser/Makefile
+++ b/lib/Target/ARM/AsmParser/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMARMAsmParser
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' ARM target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
index 2d13533..e1f386e 100644
--- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
@@ -49,7 +49,6 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include <cctype>
using namespace llvm;
@@ -160,7 +159,6 @@ namespace {
unsigned AsmVariant,
const char *ExtraCode);
- void PrintGlobalVariable(const GlobalVariable* GVar);
void printInstruction(const MachineInstr *MI); // autogenerated.
static const char *getRegisterName(unsigned RegNo);
@@ -172,7 +170,12 @@ namespace {
/// EmitMachineConstantPoolValue - Print a machine constantpool value to
/// the .s file.
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
- printDataDirective(MCPV->getType());
+ switch (TM.getTargetData()->getTypeAllocSize(MCPV->getType())) {
+ case 1: O << MAI->getData8bitsDirective(0); break;
+ case 2: O << MAI->getData16bitsDirective(0); break;
+ case 4: O << MAI->getData32bitsDirective(0); break;
+ default: assert(0 && "Unknown CPV size");
+ }
ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
SmallString<128> TmpNameStr;
@@ -184,32 +187,27 @@ namespace {
} else if (ACPV->isBlockAddress()) {
O << GetBlockAddressSymbol(ACPV->getBlockAddress())->getName();
} else if (ACPV->isGlobalValue()) {
- std::string Name;
GlobalValue *GV = ACPV->getGV();
bool isIndirect = Subtarget->isTargetDarwin() &&
Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
if (!isIndirect)
- Name = Mang->getMangledName(GV);
+ O << *GetGlobalValueSymbol(GV);
else {
// FIXME: Remove this when Darwin transition to @GOT like syntax.
- Name = Mang->getMangledName(GV, "$non_lazy_ptr", true);
- MCSymbol *Sym = OutContext.GetOrCreateSymbol(StringRef(Name));
+ MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
+ O << *Sym;
MachineModuleInfoMachO &MMIMachO =
MMI->getObjFileInfo<MachineModuleInfoMachO>();
const MCSymbol *&StubSym =
GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) :
MMIMachO.getGVStubEntry(Sym);
- if (StubSym == 0) {
- Mang->getNameWithPrefix(TmpNameStr, GV, false);
- StubSym = OutContext.GetOrCreateSymbol(TmpNameStr.str());
- }
+ if (StubSym == 0)
+ StubSym = GetGlobalValueSymbol(GV);
}
- O << Name;
} else {
assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
- Mang->getNameWithPrefix(TmpNameStr, ACPV->getSymbol());
- OutContext.GetOrCreateSymbol(TmpNameStr.str())->print(O, MAI);
+ O << *GetExternalSymbolSymbol(ACPV->getSymbol());
}
if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
@@ -219,9 +217,9 @@ namespace {
<< "+" << (unsigned)ACPV->getPCAdjustment();
if (ACPV->mustAddCurrentAddress())
O << "-.";
- O << ")";
+ O << ')';
}
- O << "\n";
+ O << '\n';
}
void getAnalysisUsage(AnalysisUsage &AU) const {
@@ -262,7 +260,7 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
case Function::InternalLinkage:
break;
case Function::ExternalLinkage:
- O << "\t.globl\t" << CurrentFnName << "\n";
+ O << "\t.globl\t" << *CurrentFnSym << "\n";
break;
case Function::LinkerPrivateLinkage:
case Function::WeakAnyLinkage:
@@ -270,15 +268,15 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
case Function::LinkOnceAnyLinkage:
case Function::LinkOnceODRLinkage:
if (Subtarget->isTargetDarwin()) {
- O << "\t.globl\t" << CurrentFnName << "\n";
- O << "\t.weak_definition\t" << CurrentFnName << "\n";
+ O << "\t.globl\t" << *CurrentFnSym << "\n";
+ O << "\t.weak_definition\t" << *CurrentFnSym << "\n";
} else {
- O << MAI->getWeakRefDirective() << CurrentFnName << "\n";
+ O << MAI->getWeakRefDirective() << *CurrentFnSym << "\n";
}
break;
}
- printVisibility(CurrentFnName, F->getVisibility());
+ printVisibility(CurrentFnSym, F->getVisibility());
unsigned FnAlign = 1 << MF.getAlignment(); // MF alignment is log2.
if (AFI->isThumbFunction()) {
@@ -286,13 +284,13 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
O << "\t.code\t16\n";
O << "\t.thumb_func";
if (Subtarget->isTargetDarwin())
- O << "\t" << CurrentFnName;
+ O << "\t" << *CurrentFnSym;
O << "\n";
} else {
EmitAlignment(FnAlign, F);
}
- O << CurrentFnName << ":\n";
+ O << *CurrentFnSym << ":\n";
// Emit pre-function debug information.
DW->BeginFunction(&MF);
@@ -320,7 +318,7 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n";
+ O << "\t.size " << *CurrentFnSym << ", .-" << *CurrentFnSym << "\n";
// Emit post-function debug information.
DW->EndFunction(&MF);
@@ -369,7 +367,7 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
break;
}
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_GlobalAddress: {
bool isCallOp = Modifier && !strcmp(Modifier, "call");
@@ -381,7 +379,7 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
(TF & ARMII::MO_HI16))
O << ":upper16:";
- O << Mang->getMangledName(GV);
+ O << *GetGlobalValueSymbol(GV);
printOffset(MO.getOffset());
@@ -392,9 +390,7 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
}
case MachineOperand::MO_ExternalSymbol: {
bool isCallOp = Modifier && !strcmp(Modifier, "call");
- SmallString<128> NameStr;
- Mang->getNameWithPrefix(NameStr, MO.getSymbolName());
- OutContext.GetOrCreateSymbol(NameStr.str())->print(O, MAI);
+ O << *GetExternalSymbolSymbol(MO.getSymbolName());
if (isCallOp && Subtarget->isTargetELF() &&
TM.getRelocationModel() == Reloc::PIC_)
@@ -402,12 +398,10 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
break;
}
case MachineOperand::MO_ConstantPoolIndex:
- O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
- << '_' << MO.getIndex();
+ O << *GetCPISymbol(MO.getIndex());
break;
case MachineOperand::MO_JumpTableIndex:
- O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
- << '_' << MO.getIndex();
+ O << *GetJTISymbol(MO.getIndex());
break;
}
}
@@ -895,8 +889,7 @@ void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNum,
// data itself.
if (!strcmp(Modifier, "label")) {
unsigned ID = MI->getOperand(OpNum).getImm();
- O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
- << '_' << ID << ":\n";
+ O << *GetCPISymbol(ID) << ":\n";
} else {
assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
unsigned CPI = MI->getOperand(OpNum).getIndex();
@@ -916,6 +909,7 @@ void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) {
const MachineOperand &MO1 = MI->getOperand(OpNum);
const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
+
unsigned JTI = MO1.getIndex();
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
<< '_' << JTI << '_' << MO2.getImm() << ":\n";
@@ -941,11 +935,11 @@ void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) {
<< '_' << JTI << '_' << MO2.getImm()
<< "_set_" << MBB->getNumber();
else if (TM.getRelocationModel() == Reloc::PIC_) {
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
- O << '-' << MAI->getPrivateGlobalPrefix() << "JTI"
+ O << *GetMBBSymbol(MBB->getNumber())
+ << '-' << MAI->getPrivateGlobalPrefix() << "JTI"
<< getFunctionNumber() << '_' << JTI << '_' << MO2.getImm();
} else {
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MBB->getNumber());
}
if (i != e-1)
O << '\n';
@@ -976,13 +970,11 @@ void ARMAsmPrinter::printJT2BlockOperand(const MachineInstr *MI, int OpNum) {
else if (HalfWordOffset)
O << MAI->getData16bitsDirective();
if (ByteOffset || HalfWordOffset) {
- O << '(';
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
+ O << '(' << *GetMBBSymbol(MBB->getNumber());
O << "-" << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
<< '_' << JTI << '_' << MO2.getImm() << ")/2";
} else {
- O << "\tb.w ";
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
+ O << "\tb.w " << *GetMBBSymbol(MBB->getNumber());
}
if (i != e-1)
O << '\n';
@@ -1174,146 +1166,6 @@ void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
}
}
-void ARMAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer()) // External global require no code
- return;
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
-
- if (EmitSpecialLLVMGlobal(GVar)) {
- if (Subtarget->isTargetDarwin() &&
- TM.getRelocationModel() == Reloc::Static) {
- if (GVar->getName() == "llvm.global_ctors")
- O << ".reference .constructors_used\n";
- else if (GVar->getName() == "llvm.global_dtors")
- O << ".reference .destructors_used\n";
- }
- return;
- }
-
- std::string name = Mang->getMangledName(GVar);
- Constant *C = GVar->getInitializer();
- const Type *Type = C->getType();
- unsigned Size = TD->getTypeAllocSize(Type);
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
- bool isDarwin = Subtarget->isTargetDarwin();
-
- printVisibility(name, GVar->getVisibility());
-
- if (Subtarget->isTargetELF())
- O << "\t.type " << name << ",%object\n";
-
- const MCSection *TheSection =
- getObjFileLowering().SectionForGlobal(GVar, Mang, TM);
- OutStreamer.SwitchSection(TheSection);
-
- // FIXME: get this stuff from section kind flags.
- if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal() &&
- // Don't put things that should go in the cstring section into "comm".
- !TheSection->getKind().isMergeableCString()) {
- if (GVar->hasExternalLinkage()) {
- if (const char *Directive = MAI->getZeroFillDirective()) {
- O << "\t.globl\t" << name << "\n";
- O << Directive << "__DATA, __common, " << name << ", "
- << Size << ", " << Align << "\n";
- return;
- }
- }
-
- if (GVar->hasLocalLinkage() || GVar->isWeakForLinker()) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (isDarwin) {
- if (GVar->hasLocalLinkage()) {
- O << MAI->getLCOMMDirective() << name << "," << Size
- << ',' << Align;
- } else if (GVar->hasCommonLinkage()) {
- O << MAI->getCOMMDirective() << name << "," << Size
- << ',' << Align;
- } else {
- OutStreamer.SwitchSection(TheSection);
- O << "\t.globl " << name << '\n'
- << MAI->getWeakDefDirective() << name << '\n';
- EmitAlignment(Align, GVar);
- O << name << ":";
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- EmitGlobalConstant(C);
- return;
- }
- } else if (MAI->getLCOMMDirective() != NULL) {
- if (GVar->hasLocalLinkage()) {
- O << MAI->getLCOMMDirective() << name << "," << Size;
- } else {
- O << MAI->getCOMMDirective() << name << "," << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
- }
- } else {
- if (GVar->hasLocalLinkage())
- O << "\t.local\t" << name << "\n";
- O << MAI->getCOMMDirective() << name << "," << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << "," << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
- }
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << "\n";
- return;
- }
- }
-
- switch (GVar->getLinkage()) {
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- if (isDarwin) {
- O << "\t.globl " << name << "\n"
- << "\t.weak_definition " << name << "\n";
- } else {
- O << "\t.weak " << name << "\n";
- }
- break;
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- O << "\t.globl " << name << "\n";
- break;
- case GlobalValue::PrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
- O << name << ":";
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << "\n";
- if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size " << name << ", " << Size << "\n";
-
- EmitGlobalConstant(C);
- O << '\n';
-}
-
void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
if (Subtarget->isTargetDarwin()) {
@@ -1333,10 +1185,8 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
EmitAlignment(2);
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- Stubs[i].first->print(O, MAI);
- O << ":\n\t.indirect_symbol ";
- Stubs[i].second->print(O, MAI);
- O << "\n\t.long\t0\n";
+ O << *Stubs[i].first << ":\n\t.indirect_symbol ";
+ O << *Stubs[i].second << "\n\t.long\t0\n";
}
}
@@ -1344,12 +1194,8 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
if (!Stubs.empty()) {
OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
EmitAlignment(2);
- for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- Stubs[i].first->print(O, MAI);
- O << ":\n\t.long ";
- Stubs[i].second->print(O, MAI);
- O << "\n";
- }
+ for (unsigned i = 0, e = Stubs.size(); i != e; ++i)
+ O << *Stubs[i].first << ":\n\t.long " << *Stubs[i].second << "\n";
}
// Funny Darwin hack: This flag tells the linker that no global symbols
@@ -1357,7 +1203,7 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
// implementation of multiple entry points). If this doesn't occur, the
// linker can safely perform dead code stripping. Since LLVM never
// generates code that does this, it is always safe to set.
- OutStreamer.EmitAssemblerFlag(MCStreamer::SubsectionsViaSymbols);
+ OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
}
}
@@ -1416,12 +1262,7 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex();
EmitAlignment(2);
-
- const char *Prefix = MAI->getPrivateGlobalPrefix();
- MCSymbol *Label = OutContext.GetOrCreateSymbol(Twine(Prefix)+"CPI"+
- Twine(getFunctionNumber())+
- "_"+ Twine(LabelId));
- OutStreamer.EmitLabel(Label);
+ OutStreamer.EmitLabel(GetCPISymbol(LabelId));
const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
if (MCPE.isMachineConstantPoolEntry())
diff --git a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
index 9fc57e0..6885ecb 100644
--- a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
@@ -62,7 +62,7 @@ void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
} else {
assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
assert(Op.isExpr() && "unknown operand kind in printOperand");
- Op.getExpr()->print(O, &MAI);
+ O << *Op.getExpr();
}
}
diff --git a/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp b/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp
index c49fee3..f843ee2 100644
--- a/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp
@@ -22,7 +22,6 @@
#include "llvm/MC/MCInst.h"
//#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/ADT/SmallString.h"
using namespace llvm;
@@ -40,33 +39,24 @@ MachineModuleInfoMachO &ARMMCInstLower::getMachOMMI() const {
MCSymbol *ARMMCInstLower::
GetGlobalAddressSymbol(const MachineOperand &MO) const {
- const GlobalValue *GV = MO.getGlobal();
-
- SmallString<128> Name;
- Mang.getNameWithPrefix(Name, GV, false);
-
// FIXME: HANDLE PLT references how??
switch (MO.getTargetFlags()) {
default: assert(0 && "Unknown target flag on GV operand");
case 0: break;
}
- return Ctx.GetOrCreateSymbol(Name.str());
+ return Printer.GetGlobalValueSymbol(MO.getGlobal());
}
MCSymbol *ARMMCInstLower::
GetExternalSymbolSymbol(const MachineOperand &MO) const {
- SmallString<128> Name;
- Name += Printer.MAI->getGlobalPrefix();
- Name += MO.getSymbolName();
-
// FIXME: HANDLE PLT references how??
switch (MO.getTargetFlags()) {
default: assert(0 && "Unknown target flag on GV operand");
case 0: break;
}
- return Ctx.GetOrCreateSymbol(Name.str());
+ return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
}
diff --git a/lib/Target/ARM/AsmPrinter/Makefile b/lib/Target/ARM/AsmPrinter/Makefile
index 208becc..93b8fc9 100644
--- a/lib/Target/ARM/AsmPrinter/Makefile
+++ b/lib/Target/ARM/AsmPrinter/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMARMAsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' arm target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/ARM/Makefile b/lib/Target/ARM/Makefile
index a8dd38c..b766a86 100644
--- a/lib/Target/ARM/Makefile
+++ b/lib/Target/ARM/Makefile
@@ -10,6 +10,7 @@
LEVEL = ../../..
LIBRARYNAME = LLVMARMCodeGen
TARGET = ARM
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = ARMGenRegisterInfo.h.inc ARMGenRegisterNames.inc \
diff --git a/lib/Target/ARM/README.txt b/lib/Target/ARM/README.txt
index 11c48ad..a6f26a5 100644
--- a/lib/Target/ARM/README.txt
+++ b/lib/Target/ARM/README.txt
@@ -596,3 +596,12 @@ Make use of the "rbit" instruction.
Take a look at test/CodeGen/Thumb2/machine-licm.ll. ARM should be taught how
to licm and cse the unnecessary load from cp#1.
+
+//===---------------------------------------------------------------------===//
+
+The CMN instruction sets the flags like an ADD instruction, while CMP sets
+them like a subtract. Therefore to be able to use CMN for comparisons other
+than the Z bit, we'll need additional logic to reverse the conditionals
+associated with the comparison. Perhaps a pseudo-instruction for the comparison,
+with a post-codegen pass to clean up and handle the condition codes?
+See PR5694 for testcase.
diff --git a/lib/Target/ARM/TargetInfo/Makefile b/lib/Target/ARM/TargetInfo/Makefile
index 6292ab1..589dbe5 100644
--- a/lib/Target/ARM/TargetInfo/Makefile
+++ b/lib/Target/ARM/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMARMInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/ARM/Thumb1InstrInfo.cpp b/lib/Target/ARM/Thumb1InstrInfo.cpp
index e875394..7f42c82 100644
--- a/lib/Target/ARM/Thumb1InstrInfo.cpp
+++ b/lib/Target/ARM/Thumb1InstrInfo.cpp
@@ -105,7 +105,9 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
(TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
isARMLowRegister(SrcReg))) && "Unknown regclass!");
- if (RC == ARM::tGPRRegisterClass) {
+ if (RC == ARM::tGPRRegisterClass ||
+ (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
+ isARMLowRegister(SrcReg))) {
MachineFunction &MF = *MBB.getParent();
MachineFrameInfo &MFI = *MF.getFrameInfo();
MachineMemOperand *MMO =
@@ -130,7 +132,9 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
(TargetRegisterInfo::isPhysicalRegister(DestReg) &&
isARMLowRegister(DestReg))) && "Unknown regclass!");
- if (RC == ARM::tGPRRegisterClass) {
+ if (RC == ARM::tGPRRegisterClass ||
+ (TargetRegisterInfo::isPhysicalRegister(DestReg) &&
+ isARMLowRegister(DestReg))) {
MachineFunction &MF = *MBB.getParent();
MachineFrameInfo &MFI = *MF.getFrameInfo();
MachineMemOperand *MMO =
diff --git a/lib/Target/ARM/Thumb1RegisterInfo.cpp b/lib/Target/ARM/Thumb1RegisterInfo.cpp
index 9f3816a..d6630ce 100644
--- a/lib/Target/ARM/Thumb1RegisterInfo.cpp
+++ b/lib/Target/ARM/Thumb1RegisterInfo.cpp
@@ -479,11 +479,15 @@ Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
"Thumb add/sub sp, #imm immediate must be multiple of 4!");
}
- if (Offset == 0) {
+ unsigned PredReg;
+ if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) {
// Turn it into a move.
MI.setDesc(TII.get(ARM::tMOVgpr2tgpr));
MI.getOperand(i).ChangeToRegister(FrameReg, false);
- MI.RemoveOperand(i+1);
+ // Remove offset and remaining explicit predicate operands.
+ do MI.RemoveOperand(i+1);
+ while (MI.getNumOperands() > i+1 &&
+ (!MI.getOperand(i+1).isReg() || !MI.getOperand(i+1).isImm()));
return 0;
}
diff --git a/lib/Target/ARM/Thumb2InstrInfo.cpp b/lib/Target/ARM/Thumb2InstrInfo.cpp
index f4a8c27..387edaf 100644
--- a/lib/Target/ARM/Thumb2InstrInfo.cpp
+++ b/lib/Target/ARM/Thumb2InstrInfo.cpp
@@ -329,12 +329,16 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
Offset += MI.getOperand(FrameRegIdx+1).getImm();
bool isSP = FrameReg == ARM::SP;
- if (Offset == 0) {
+ unsigned PredReg;
+ if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) {
// Turn it into a move.
MI.setDesc(TII.get(ARM::tMOVgpr2gpr));
MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
- MI.RemoveOperand(FrameRegIdx+1);
- Offset = 0;
+ // Remove offset and remaining explicit predicate operands.
+ do MI.RemoveOperand(FrameRegIdx+1);
+ while (MI.getNumOperands() > FrameRegIdx+1 &&
+ (!MI.getOperand(FrameRegIdx+1).isReg() ||
+ !MI.getOperand(FrameRegIdx+1).isImm()));
return true;
}
diff --git a/lib/Target/ARM/Thumb2SizeReduction.cpp b/lib/Target/ARM/Thumb2SizeReduction.cpp
index 35359aa..95288bf 100644
--- a/lib/Target/ARM/Thumb2SizeReduction.cpp
+++ b/lib/Target/ARM/Thumb2SizeReduction.cpp
@@ -65,7 +65,8 @@ namespace {
{ ARM::t2ASRri, ARM::tASRri, 0, 5, 0, 1, 0, 0,0, 0 },
{ ARM::t2ASRrr, 0, ARM::tASRrr, 0, 0, 0, 1, 0,0, 0 },
{ ARM::t2BICrr, 0, ARM::tBIC, 0, 0, 0, 1, 0,0, 0 },
- { ARM::t2CMNrr, ARM::tCMN, 0, 0, 0, 1, 0, 2,0, 0 },
+ //FIXME: Disable CMN, as CCodes are backwards from compare expectations
+ //{ ARM::t2CMNrr, ARM::tCMN, 0, 0, 0, 1, 0, 2,0, 0 },
{ ARM::t2CMPri, ARM::tCMPi8, 0, 8, 0, 1, 0, 2,0, 0 },
{ ARM::t2CMPrr, ARM::tCMPhir, 0, 0, 0, 0, 0, 2,0, 0 },
{ ARM::t2CMPzri,ARM::tCMPzi8, 0, 8, 0, 1, 0, 2,0, 0 },
diff --git a/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp b/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
index 338057b..b13f544 100644
--- a/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
+++ b/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
@@ -28,7 +28,6 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/ADT/Statistic.h"
using namespace llvm;
@@ -53,7 +52,6 @@ namespace {
void printOp(const MachineOperand &MO, bool IsCallOp = false);
void printOperand(const MachineInstr *MI, int opNum);
void printBaseOffsetPair(const MachineInstr *MI, int i, bool brackets=true);
- void PrintGlobalVariable(const GlobalVariable *GVar);
bool runOnMachineFunction(MachineFunction &F);
void EmitStartOfAsmFile(Module &M);
@@ -95,7 +93,7 @@ void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
return;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_ConstantPoolIndex:
@@ -108,7 +106,7 @@ void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
return;
case MachineOperand::MO_GlobalAddress:
- O << Mang->getMangledName(MO.getGlobal());
+ O << *GetGlobalValueSymbol(MO.getGlobal());
return;
case MachineOperand::MO_JumpTableIndex:
@@ -148,29 +146,29 @@ bool AlphaAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
case Function::PrivateLinkage:
case Function::LinkerPrivateLinkage:
break;
- case Function::ExternalLinkage:
- O << "\t.globl " << CurrentFnName << "\n";
- break;
+ case Function::ExternalLinkage:
+ O << "\t.globl " << *CurrentFnSym << '\n';
+ break;
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
case Function::LinkOnceAnyLinkage:
case Function::LinkOnceODRLinkage:
- O << MAI->getWeakRefDirective() << CurrentFnName << "\n";
+ O << MAI->getWeakRefDirective() << *CurrentFnSym << '\n';
break;
}
- printVisibility(CurrentFnName, F->getVisibility());
+ printVisibility(CurrentFnSym, F->getVisibility());
- O << "\t.ent " << CurrentFnName << "\n";
+ O << "\t.ent " << *CurrentFnSym << "\n";
- O << CurrentFnName << ":\n";
+ O << *CurrentFnSym << ":\n";
// Print out code for the function.
for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
I != E; ++I) {
- if (I != MF.begin()) {
+ if (I != MF.begin())
EmitBasicBlockStart(I);
- }
+
for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
II != E; ++II) {
// Print the assembly for the instruction.
@@ -185,7 +183,7 @@ bool AlphaAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
}
- O << "\t.end " << CurrentFnName << "\n";
+ O << "\t.end " << *CurrentFnSym << "\n";
// We didn't modify anything.
return false;
@@ -199,62 +197,6 @@ void AlphaAsmPrinter::EmitStartOfAsmFile(Module &M) {
O << "\t.set noat\n";
}
-void AlphaAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer()) return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- std::string name = Mang->getMangledName(GVar);
- Constant *C = GVar->getInitializer();
- unsigned Size = TD->getTypeAllocSize(C->getType());
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
-
- // 0: Switch to section
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- // 1: Check visibility
- printVisibility(name, GVar->getVisibility());
-
- // 2: Kind
- switch (GVar->getLinkage()) {
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::CommonLinkage:
- O << MAI->getWeakRefDirective() << name << '\n';
- break;
- case GlobalValue::AppendingLinkage:
- case GlobalValue::ExternalLinkage:
- O << MAI->getGlobalDirective() << name << "\n";
- break;
- case GlobalValue::InternalLinkage:
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- break;
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- // 3: Type, Size, Align
- if (MAI->hasDotTypeDotSizeDirective()) {
- O << "\t.type\t" << name << ", @object\n";
- O << "\t.size\t" << name << ", " << Size << "\n";
- }
-
- EmitAlignment(Align, GVar);
-
- O << name << ":\n";
-
- EmitGlobalConstant(C);
- O << '\n';
-}
-
/// PrintAsmOperand - Print out an operand for an inline asm expression.
///
bool AlphaAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
diff --git a/lib/Target/Alpha/AsmPrinter/Makefile b/lib/Target/Alpha/AsmPrinter/Makefile
index 3c64a3c..3f64aac 100644
--- a/lib/Target/Alpha/AsmPrinter/Makefile
+++ b/lib/Target/Alpha/AsmPrinter/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMAlphaAsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' alpha target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/Alpha/Makefile b/lib/Target/Alpha/Makefile
index d2d7109..14cbc6c 100644
--- a/lib/Target/Alpha/Makefile
+++ b/lib/Target/Alpha/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMAlphaCodeGen
TARGET = Alpha
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = AlphaGenRegisterInfo.h.inc AlphaGenRegisterNames.inc \
diff --git a/lib/Target/Alpha/TargetInfo/Makefile b/lib/Target/Alpha/TargetInfo/Makefile
index de01d7f..6f7b898 100644
--- a/lib/Target/Alpha/TargetInfo/Makefile
+++ b/lib/Target/Alpha/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMAlphaInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp b/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp
index 0bd94d4..749f735 100644
--- a/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp
+++ b/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp
@@ -30,7 +30,6 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ErrorHandling.h"
@@ -55,13 +54,12 @@ namespace {
void printInstruction(const MachineInstr *MI); // autogenerated.
static const char *getRegisterName(unsigned RegNo);
- void emitLinkage(const std::string &n, GlobalValue::LinkageTypes l);
+ void emitLinkage(const MCSymbol *GVSym, GlobalValue::LinkageTypes l);
bool runOnMachineFunction(MachineFunction &F);
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode);
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode);
- void PrintGlobalVariable(const GlobalVariable* GVar);
};
} // end of anonymous namespace
@@ -71,48 +69,27 @@ extern "C" void LLVMInitializeBlackfinAsmPrinter() {
RegisterAsmPrinter<BlackfinAsmPrinter> X(TheBlackfinTarget);
}
-void BlackfinAsmPrinter::emitLinkage(const std::string &name,
- GlobalValue::LinkageTypes l) {
- switch (l) {
+void BlackfinAsmPrinter::emitLinkage(const MCSymbol *GVSym,
+ GlobalValue::LinkageTypes L) {
+ switch (L) {
default: llvm_unreachable("Unknown linkage type!");
case GlobalValue::InternalLinkage: // Symbols default to internal.
case GlobalValue::PrivateLinkage:
case GlobalValue::LinkerPrivateLinkage:
break;
case GlobalValue::ExternalLinkage:
- O << MAI->getGlobalDirective() << name << "\n";
+ O << MAI->getGlobalDirective() << *GVSym << "\n";
break;
case GlobalValue::LinkOnceAnyLinkage:
case GlobalValue::LinkOnceODRLinkage:
case GlobalValue::WeakAnyLinkage:
case GlobalValue::WeakODRLinkage:
- O << MAI->getGlobalDirective() << name << "\n";
- O << MAI->getWeakDefDirective() << name << "\n";
+ O << MAI->getGlobalDirective() << *GVSym << "\n";
+ O << MAI->getWeakDefDirective() << *GVSym << "\n";
break;
}
}
-void BlackfinAsmPrinter::PrintGlobalVariable(const GlobalVariable* GV) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GV->hasInitializer() || EmitSpecialLLVMGlobal(GV))
- return;
-
- std::string name = Mang->getMangledName(GV);
- Constant *C = GV->getInitializer();
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GV, Mang,
- TM));
- emitLinkage(name, GV->getLinkage());
- EmitAlignment(TD->getPreferredAlignmentLog(GV), GV);
- printVisibility(name, GV->getVisibility());
-
- O << "\t.type " << name << ", STT_OBJECT\n";
- O << "\t.size " << name << ',' << TD->getTypeAllocSize(C->getType()) << '\n';
- O << name << ":\n";
- EmitGlobalConstant(C);
-}
-
/// runOnMachineFunction - This uses the printInstruction()
/// method to print assembly for each instruction.
///
@@ -124,11 +101,11 @@ bool BlackfinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
const Function *F = MF.getFunction();
OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
EmitAlignment(2, F);
- emitLinkage(CurrentFnName, F->getLinkage());
- printVisibility(CurrentFnName, F->getVisibility());
+ emitLinkage(CurrentFnSym, F->getLinkage());
+ printVisibility(CurrentFnSym, F->getVisibility());
- O << "\t.type\t" << CurrentFnName << ", STT_FUNC\n"
- << CurrentFnName << ":\n";
+ O << "\t.type\t" << *CurrentFnSym << ", STT_FUNC\n";
+ O << *CurrentFnSym << ":\n";
if (DW)
DW->BeginFunction(&MF);
@@ -154,7 +131,7 @@ bool BlackfinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
}
- O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n";
+ O << "\t.size " << *CurrentFnSym << ", .-" << *CurrentFnSym << "\n";
if (DW)
DW->EndFunction(&MF);
@@ -175,18 +152,15 @@ void BlackfinAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
O << MO.getImm();
break;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_GlobalAddress:
- O << Mang->getMangledName(MO.getGlobal());
+ O << *GetGlobalValueSymbol(MO.getGlobal());
printOffset(MO.getOffset());
break;
- case MachineOperand::MO_ExternalSymbol: {
- SmallString<60> NameStr;
- Mang->getNameWithPrefix(NameStr, MO.getSymbolName());
- OutContext.GetOrCreateSymbol(NameStr.str())->print(O, MAI);
+ case MachineOperand::MO_ExternalSymbol:
+ O << *GetExternalSymbolSymbol(MO.getSymbolName());
break;
- }
case MachineOperand::MO_ConstantPoolIndex:
O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
<< MO.getIndex();
diff --git a/lib/Target/Blackfin/AsmPrinter/Makefile b/lib/Target/Blackfin/AsmPrinter/Makefile
index 091d4df..30e8285 100644
--- a/lib/Target/Blackfin/AsmPrinter/Makefile
+++ b/lib/Target/Blackfin/AsmPrinter/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMBlackfinAsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' Blackfin target directory to grab private
# headers
diff --git a/lib/Target/Blackfin/Makefile b/lib/Target/Blackfin/Makefile
index c68760b..4fdaf27 100644
--- a/lib/Target/Blackfin/Makefile
+++ b/lib/Target/Blackfin/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMBlackfinCodeGen
TARGET = Blackfin
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = BlackfinGenRegisterInfo.h.inc BlackfinGenRegisterNames.inc \
diff --git a/lib/Target/Blackfin/TargetInfo/Makefile b/lib/Target/Blackfin/TargetInfo/Makefile
index c49cfbe..5c770cf 100644
--- a/lib/Target/Blackfin/TargetInfo/Makefile
+++ b/lib/Target/Blackfin/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMBlackfinInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index 0fd975c..e765655 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -33,6 +33,7 @@
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/IntrinsicLowering.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSymbol.h"
@@ -44,7 +45,6 @@
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/InstVisitor.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/System/Host.h"
#include "llvm/Config/config.h"
@@ -58,6 +58,13 @@ extern "C" void LLVMInitializeCBackendTarget() {
}
namespace {
+ class CBEMCAsmInfo : public MCAsmInfo {
+ public:
+ CBEMCAsmInfo() {
+ GlobalPrefix = "";
+ PrivateGlobalPrefix = "";
+ }
+ };
/// CBackendNameAllUsedStructsAndMergeFunctions - This pass inserts names for
/// any unnamed structure types that are used by the program, and merges
/// external functions with the same name.
@@ -344,11 +351,19 @@ namespace {
char CWriter::ID = 0;
-static std::string Mangle(const std::string &S) {
+static std::string CBEMangle(const std::string &S) {
std::string Result;
- raw_string_ostream OS(Result);
- MCSymbol::printMangledName(S, OS, 0);
- return OS.str();
+
+ for (unsigned i = 0, e = S.size(); i != e; ++i)
+ if (isalnum(S[i]) || S[i] == '_') {
+ Result += S[i];
+ } else {
+ Result += '_';
+ Result += 'A'+(S[i]&15);
+ Result += 'A'+((S[i]>>4)&15);
+ Result += '_';
+ }
+ return Result;
}
@@ -1445,7 +1460,7 @@ std::string CWriter::GetValueName(const Value *Operand) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(Operand)) {
SmallString<128> Str;
Mang->getNameWithPrefix(Str, GV, false);
- return Mangle(Str.str().str());
+ return CBEMangle(Str.str().str());
}
std::string Name = Operand->getName();
@@ -1869,8 +1884,17 @@ bool CWriter::doInitialization(Module &M) {
IL = new IntrinsicLowering(*TD);
IL->AddPrototypes(M);
- // Ensure that all structure types have names...
- Mang = new Mangler(M);
+#if 0
+ std::string Triple = TheModule->getTargetTriple();
+ if (Triple.empty())
+ Triple = llvm::sys::getHostTriple();
+
+ std::string E;
+ if (const Target *Match = TargetRegistry::lookupTarget(Triple, E))
+ TAsm = Match->createAsmInfo(Triple);
+#endif
+ TAsm = new CBEMCAsmInfo();
+ Mang = new Mangler(*TAsm);
// Keep track of which functions are static ctors/dtors so they can have
// an attribute added to their prototypes.
@@ -2223,7 +2247,7 @@ void CWriter::printModuleTypes(const TypeSymbolTable &TST) {
// Print out forward declarations for structure types before anything else!
Out << "/* Structure forward decls */\n";
for (; I != End; ++I) {
- std::string Name = "struct " + Mangle("l_"+I->first);
+ std::string Name = "struct " + CBEMangle("l_"+I->first);
Out << Name << ";\n";
TypeNames.insert(std::make_pair(I->second, Name));
}
@@ -2234,7 +2258,7 @@ void CWriter::printModuleTypes(const TypeSymbolTable &TST) {
// for struct or opaque types.
Out << "/* Typedefs */\n";
for (I = TST.begin(); I != End; ++I) {
- std::string Name = Mangle("l_"+I->first);
+ std::string Name = CBEMangle("l_"+I->first);
Out << "typedef ";
printType(Out, I->second, false, Name);
Out << ";\n";
@@ -3240,30 +3264,31 @@ bool CWriter::visitBuiltinCall(CallInst &I, Intrinsic::ID ID,
// of the per target tables
// handle multiple constraint codes
std::string CWriter::InterpretASMConstraint(InlineAsm::ConstraintInfo& c) {
-
assert(c.Codes.size() == 1 && "Too many asm constraint codes to handle");
- const char *const *table = 0;
-
// Grab the translation table from MCAsmInfo if it exists.
- if (!TAsm) {
- std::string Triple = TheModule->getTargetTriple();
- if (Triple.empty())
- Triple = llvm::sys::getHostTriple();
-
- std::string E;
- if (const Target *Match = TargetRegistry::lookupTarget(Triple, E))
- TAsm = Match->createAsmInfo(Triple);
- }
- if (TAsm)
- table = TAsm->getAsmCBE();
+ const MCAsmInfo *TargetAsm;
+ std::string Triple = TheModule->getTargetTriple();
+ if (Triple.empty())
+ Triple = llvm::sys::getHostTriple();
+
+ std::string E;
+ if (const Target *Match = TargetRegistry::lookupTarget(Triple, E))
+ TargetAsm = Match->createAsmInfo(Triple);
+ else
+ return c.Codes[0];
+
+ const char *const *table = TargetAsm->getAsmCBE();
// Search the translation table if it exists.
for (int i = 0; table && table[i]; i += 2)
- if (c.Codes[0] == table[i])
+ if (c.Codes[0] == table[i]) {
+ delete TargetAsm;
return table[i+1];
+ }
// Default is identity.
+ delete TargetAsm;
return c.Codes[0];
}
diff --git a/lib/Target/CBackend/Makefile b/lib/Target/CBackend/Makefile
index 3b5ef0f..f82d277 100644
--- a/lib/Target/CBackend/Makefile
+++ b/lib/Target/CBackend/Makefile
@@ -9,6 +9,7 @@
LEVEL = ../../..
LIBRARYNAME = LLVMCBackend
+CXXFLAGS = -fno-rtti
DIRS = TargetInfo
diff --git a/lib/Target/CBackend/TargetInfo/Makefile b/lib/Target/CBackend/TargetInfo/Makefile
index d4d5e15..6407904 100644
--- a/lib/Target/CBackend/TargetInfo/Makefile
+++ b/lib/Target/CBackend/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMCBackendInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/CMakeLists.txt b/lib/Target/CMakeLists.txt
index 8769ee2..10478b4 100644
--- a/lib/Target/CMakeLists.txt
+++ b/lib/Target/CMakeLists.txt
@@ -1,6 +1,8 @@
add_llvm_library(LLVMTarget
+ Mangler.cpp
SubtargetFeature.cpp
Target.cpp
+ TargetAsmLexer.cpp
TargetData.cpp
TargetELFWriterInfo.cpp
TargetFrameInfo.cpp
diff --git a/lib/Target/CellSPU/AsmPrinter/Makefile b/lib/Target/CellSPU/AsmPrinter/Makefile
index 69639ef..aa0db52 100644
--- a/lib/Target/CellSPU/AsmPrinter/Makefile
+++ b/lib/Target/CellSPU/AsmPrinter/Makefile
@@ -9,6 +9,7 @@
LEVEL = ../../../..
LIBRARYNAME = LLVMCellSPUAsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' CellSPU target directory to grab
# private headers
diff --git a/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp b/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
index dc9f81c4..59d6ddd 100644
--- a/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
+++ b/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
@@ -39,9 +39,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
-#include <set>
using namespace llvm;
namespace {
@@ -50,7 +48,6 @@ namespace {
const std::string bss_section(".bss");
class SPUAsmPrinter : public AsmPrinter {
- std::set<std::string> FnStubs, GVStubs;
public:
explicit SPUAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
const MCAsmInfo *T, bool V) :
@@ -302,9 +299,6 @@ namespace {
AU.addRequired<DwarfWriter>();
SPUAsmPrinter::getAnalysisUsage(AU);
}
-
- //! Emit a global variable according to its section and type
- void PrintGlobalVariable(const GlobalVariable* GVar);
};
} // end of anonymous namespace
@@ -318,7 +312,7 @@ void SPUAsmPrinter::printOp(const MachineOperand &MO) {
return;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
@@ -331,32 +325,25 @@ void SPUAsmPrinter::printOp(const MachineOperand &MO) {
case MachineOperand::MO_ExternalSymbol:
// Computing the address of an external symbol, not calling it.
if (TM.getRelocationModel() != Reloc::Static) {
- std::string Name(MAI->getGlobalPrefix()); Name += MO.getSymbolName();
- GVStubs.insert(Name);
- O << "L" << Name << "$non_lazy_ptr";
+ O << "L" << MAI->getGlobalPrefix() << MO.getSymbolName()
+ << "$non_lazy_ptr";
return;
}
- O << MAI->getGlobalPrefix() << MO.getSymbolName();
+ O << *GetExternalSymbolSymbol(MO.getSymbolName());
return;
- case MachineOperand::MO_GlobalAddress: {
- // Computing the address of a global symbol, not calling it.
- GlobalValue *GV = MO.getGlobal();
- std::string Name = Mang->getMangledName(GV);
-
+ case MachineOperand::MO_GlobalAddress:
// External or weakly linked global variables need non-lazily-resolved
// stubs
if (TM.getRelocationModel() != Reloc::Static) {
+ GlobalValue *GV = MO.getGlobal();
if (((GV->isDeclaration() || GV->hasWeakLinkage() ||
GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) {
- GVStubs.insert(Name);
- O << "L" << Name << "$non_lazy_ptr";
+ O << *GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
return;
}
}
- O << Name;
+ O << *GetGlobalValueSymbol(MO.getGlobal());
return;
- }
-
default:
O << "<unknown operand type: " << MO.getType() << ">";
return;
@@ -437,18 +424,19 @@ bool LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
case Function::InternalLinkage: // Symbols default to internal.
break;
case Function::ExternalLinkage:
- O << "\t.global\t" << CurrentFnName << "\n"
- << "\t.type\t" << CurrentFnName << ", @function\n";
+ O << "\t.global\t" << *CurrentFnSym << "\n" << "\t.type\t";
+ O << *CurrentFnSym << ", @function\n";
break;
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
case Function::LinkOnceAnyLinkage:
case Function::LinkOnceODRLinkage:
- O << "\t.global\t" << CurrentFnName << "\n";
- O << "\t.weak_definition\t" << CurrentFnName << "\n";
+ O << "\t.global\t" << *CurrentFnSym << "\n";
+ O << "\t.weak_definition\t" << *CurrentFnSym << "\n";
break;
}
- O << CurrentFnName << ":\n";
+
+ O << *CurrentFnSym << ":\n";
// Emit pre-function debug information.
DW->BeginFunction(&MF);
@@ -467,7 +455,7 @@ bool LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
}
- O << "\t.size\t" << CurrentFnName << ",.-" << CurrentFnName << "\n";
+ O << "\t.size\t" << *CurrentFnSym << ",.-" << *CurrentFnSym << "\n";
// Print out jump tables referenced by the function.
EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
@@ -479,93 +467,6 @@ bool LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
return false;
}
-
-/*!
- Emit a global variable according to its section, alignment, etc.
-
- \note This code was shamelessly copied from the PowerPC's assembly printer,
- which sort of screams for some kind of refactorization of common code.
- */
-void LinuxAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer())
- return;
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- std::string name = Mang->getMangledName(GVar);
-
- printVisibility(name, GVar->getVisibility());
-
- Constant *C = GVar->getInitializer();
- const Type *Type = C->getType();
- unsigned Size = TD->getTypeAllocSize(Type);
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- if (C->isNullValue() && /* FIXME: Verify correct */
- !GVar->hasSection() &&
- (GVar->hasLocalLinkage() || GVar->hasExternalLinkage() ||
- GVar->isWeakForLinker())) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasExternalLinkage()) {
- O << "\t.global " << name << '\n';
- O << "\t.type " << name << ", @object\n";
- O << name << ":\n";
- O << "\t.zero " << Size << '\n';
- } else if (GVar->hasLocalLinkage()) {
- O << MAI->getLCOMMDirective() << name << ',' << Size;
- } else {
- O << ".comm " << name << ',' << Size;
- }
- O << "\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'\n";
- return;
- }
-
- switch (GVar->getLinkage()) {
- // Should never be seen for the CellSPU platform...
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::CommonLinkage:
- O << "\t.global " << name << '\n'
- << "\t.type " << name << ", @object\n"
- << "\t.weak " << name << '\n';
- break;
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << "\t.global " << name << '\n'
- << "\t.type " << name << ", @object\n";
- // FALL THROUGH
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- default:
- llvm_report_error("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
- O << name << ":\t\t\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'\n";
-
- EmitGlobalConstant(C);
- O << '\n';
-}
-
// Force static initialization.
extern "C" void LLVMInitializeCellSPUAsmPrinter() {
RegisterAsmPrinter<LinuxAsmPrinter> X(TheCellSPUTarget);
diff --git a/lib/Target/CellSPU/Makefile b/lib/Target/CellSPU/Makefile
index 8415168..9f3ff74 100644
--- a/lib/Target/CellSPU/Makefile
+++ b/lib/Target/CellSPU/Makefile
@@ -10,6 +10,7 @@
LEVEL = ../../..
LIBRARYNAME = LLVMCellSPUCodeGen
TARGET = SPU
+CXXFLAGS = -fno-rtti
BUILT_SOURCES = SPUGenInstrNames.inc SPUGenRegisterNames.inc \
SPUGenAsmWriter.inc SPUGenCodeEmitter.inc \
diff --git a/lib/Target/CellSPU/SPUMCAsmInfo.cpp b/lib/Target/CellSPU/SPUMCAsmInfo.cpp
index 1c921ab..03cdb29 100644
--- a/lib/Target/CellSPU/SPUMCAsmInfo.cpp
+++ b/lib/Target/CellSPU/SPUMCAsmInfo.cpp
@@ -19,7 +19,7 @@ SPULinuxMCAsmInfo::SPULinuxMCAsmInfo(const Target &T, const StringRef &TT) {
SetDirective = "\t.set";
Data64bitsDirective = "\t.quad\t";
AlignmentIsInBytes = false;
- LCOMMDirective = "\t.lcomm\t";
+ HasLCOMMDirective = true;
PCSymbol = ".";
CommentString = "#";
diff --git a/lib/Target/CellSPU/TargetInfo/Makefile b/lib/Target/CellSPU/TargetInfo/Makefile
index 9cb6827..30ca5cf 100644
--- a/lib/Target/CellSPU/TargetInfo/Makefile
+++ b/lib/Target/CellSPU/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMCellSPUInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp
index a872fbd..73272bc 100644
--- a/lib/Target/CppBackend/CPPBackend.cpp
+++ b/lib/Target/CppBackend/CPPBackend.cpp
@@ -472,7 +472,6 @@ namespace {
HANDLE_ATTR(Nest);
HANDLE_ATTR(ReadNone);
HANDLE_ATTR(ReadOnly);
- HANDLE_ATTR(InlineHint);
HANDLE_ATTR(NoInline);
HANDLE_ATTR(AlwaysInline);
HANDLE_ATTR(OptimizeForSize);
diff --git a/lib/Target/CppBackend/Makefile b/lib/Target/CppBackend/Makefile
index dc9cf48..52f2aad 100644
--- a/lib/Target/CppBackend/Makefile
+++ b/lib/Target/CppBackend/Makefile
@@ -9,6 +9,7 @@
LEVEL = ../../..
LIBRARYNAME = LLVMCppBackend
+CXXFLAGS = -fno-rtti
DIRS = TargetInfo
diff --git a/lib/Target/CppBackend/TargetInfo/Makefile b/lib/Target/CppBackend/TargetInfo/Makefile
index 6e68283..7e44aab 100644
--- a/lib/Target/CppBackend/TargetInfo/Makefile
+++ b/lib/Target/CppBackend/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMCppBackendInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/MSIL/MSILWriter.cpp b/lib/Target/MSIL/MSILWriter.cpp
index b3b91da..1bc708e 100644
--- a/lib/Target/MSIL/MSILWriter.cpp
+++ b/lib/Target/MSIL/MSILWriter.cpp
@@ -102,7 +102,6 @@ bool MSILWriter::runOnFunction(Function &F) {
bool MSILWriter::doInitialization(Module &M) {
ModulePtr = &M;
- Mang = new Mangler(M);
Out << ".assembly extern mscorlib {}\n";
Out << ".assembly MSIL {}\n\n";
Out << "// External\n";
@@ -118,7 +117,6 @@ bool MSILWriter::doInitialization(Module &M) {
bool MSILWriter::doFinalization(Module &M) {
- delete Mang;
return false;
}
@@ -232,7 +230,7 @@ bool MSILWriter::isZeroValue(const Value* V) {
std::string MSILWriter::getValueName(const Value* V) {
std::string Name;
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
- Name = Mang->getMangledName(GV);
+ Name = GV->getName();
else {
unsigned &No = AnonValueNumbers[V];
if (No == 0) No = ++NextAnonValueNumber;
@@ -259,7 +257,7 @@ std::string MSILWriter::getLabelName(const std::string& Name) {
std::string MSILWriter::getLabelName(const Value* V) {
std::string Name;
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
- Name = Mang->getMangledName(GV);
+ Name = GV->getName();
else {
unsigned &No = AnonValueNumbers[V];
if (No == 0) No = ++NextAnonValueNumber;
@@ -1616,7 +1614,7 @@ const char* MSILWriter::getLibraryName(const Function* F) {
const char* MSILWriter::getLibraryName(const GlobalVariable* GV) {
- return getLibraryForSymbol(Mang->getMangledName(GV), false, CallingConv::C);
+ return getLibraryForSymbol(GV->getName(), false, CallingConv::C);
}
@@ -1674,7 +1672,7 @@ void MSILWriter::printExternals() {
std::string Tmp = getTypeName(I->getType())+getValueName(&*I);
printSimpleInstruction("ldsflda",Tmp.c_str());
Out << "\tldstr\t\"" << getLibraryName(&*I) << "\"\n";
- Out << "\tldstr\t\"" << Mang->getMangledName(&*I) << "\"\n";
+ Out << "\tldstr\t\"" << I->getName() << "\"\n";
printSimpleInstruction("call","void* $MSIL_Import(string,string)");
printIndirectSave(I->getType());
}
diff --git a/lib/Target/MSIL/MSILWriter.h b/lib/Target/MSIL/MSILWriter.h
index 2280a3b..a95ae23 100644
--- a/lib/Target/MSIL/MSILWriter.h
+++ b/lib/Target/MSIL/MSILWriter.h
@@ -27,7 +27,6 @@
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Support/Mangler.h"
namespace llvm {
extern Target TheMSILTarget;
@@ -78,7 +77,6 @@ namespace llvm {
formatted_raw_ostream &Out;
Module* ModulePtr;
const TargetData* TD;
- Mangler* Mang;
LoopInfo *LInfo;
std::vector<StaticInitializer>* InitListPtr;
std::map<const GlobalVariable*,std::vector<StaticInitializer> >
diff --git a/lib/Target/MSIL/Makefile b/lib/Target/MSIL/Makefile
index 8057cc7..9fecba5 100644
--- a/lib/Target/MSIL/Makefile
+++ b/lib/Target/MSIL/Makefile
@@ -9,6 +9,7 @@
LEVEL = ../../..
LIBRARYNAME = LLVMMSIL
+CXXFLAGS = -fno-rtti
DIRS = TargetInfo
diff --git a/lib/Target/MSIL/TargetInfo/Makefile b/lib/Target/MSIL/TargetInfo/Makefile
index 30b0950..710f5a1 100644
--- a/lib/Target/MSIL/TargetInfo/Makefile
+++ b/lib/Target/MSIL/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMMSILInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp b/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
index 145359f..6033197 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
+++ b/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
@@ -38,9 +38,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/ErrorHandling.h"
-
using namespace llvm;
STATISTIC(EmittedInsts, "Number of machine instrs printed");
@@ -80,7 +78,6 @@ namespace {
const char *ExtraCode);
void printInstructionThroughMCStreamer(const MachineInstr *MI);
- void PrintGlobalVariable(const GlobalVariable* GVar);
void emitFunctionHeader(const MachineFunction &MF);
bool runOnMachineFunction(MachineFunction &F);
@@ -91,89 +88,6 @@ namespace {
};
} // end of anonymous namespace
-void MSP430AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
- if (!GVar->hasInitializer())
- return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- const TargetData *TD = TM.getTargetData();
-
- std::string name = Mang->getMangledName(GVar);
- Constant *C = GVar->getInitializer();
- unsigned Size = TD->getTypeAllocSize(C->getType());
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
-
- printVisibility(name, GVar->getVisibility());
-
- O << "\t.type\t" << name << ",@object\n";
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- if (C->isNullValue() && !GVar->hasSection() &&
- !GVar->isThreadLocal() &&
- (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
-
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasLocalLinkage())
- O << "\t.local\t" << name << '\n';
-
- O << MAI->getCOMMDirective() << name << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
-
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- return;
- }
-
- switch (GVar->getLinkage()) {
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- O << "\t.weak\t" << name << '\n';
- break;
- case GlobalValue::DLLExportLinkage:
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << "\t.globl " << name << '\n';
- // FALL THROUGH
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- default:
- assert(0 && "Unknown linkage type!");
- }
-
- // Use 16-bit alignment by default to simplify bunch of stuff
- EmitAlignment(Align, GVar);
- O << name << ":";
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
-
- EmitGlobalConstant(C);
-
- if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << name << ", " << Size << '\n';
-}
void MSP430AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
const Function *F = MF.getFunction();
@@ -190,20 +104,20 @@ void MSP430AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
case Function::LinkerPrivateLinkage:
break;
case Function::ExternalLinkage:
- O << "\t.globl\t" << CurrentFnName << '\n';
+ O << "\t.globl\t" << *CurrentFnSym << '\n';
break;
case Function::LinkOnceAnyLinkage:
case Function::LinkOnceODRLinkage:
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
- O << "\t.weak\t" << CurrentFnName << '\n';
+ O << "\t.weak\t" << *CurrentFnSym << '\n';
break;
}
- printVisibility(CurrentFnName, F->getVisibility());
+ printVisibility(CurrentFnSym, F->getVisibility());
- O << "\t.type\t" << CurrentFnName << ",@function\n"
- << CurrentFnName << ":\n";
+ O << "\t.type\t" << *CurrentFnSym << ",@function\n";
+ O << *CurrentFnSym << ":\n";
}
bool MSP430AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
@@ -226,7 +140,7 @@ bool MSP430AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n';
+ O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
// We didn't modify anything
return false;
@@ -259,18 +173,18 @@ void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_GlobalAddress: {
bool isMemOp = Modifier && !strcmp(Modifier, "mem");
- std::string Name = Mang->getMangledName(MO.getGlobal());
uint64_t Offset = MO.getOffset();
O << (isMemOp ? '&' : '#');
if (Offset)
O << '(' << Offset << '+';
- O << Name;
+ O << *GetGlobalValueSymbol(MO.getGlobal());
+
if (Offset)
O << ')';
@@ -278,11 +192,8 @@ void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
}
case MachineOperand::MO_ExternalSymbol: {
bool isMemOp = Modifier && !strcmp(Modifier, "mem");
- std::string Name(MAI->getGlobalPrefix());
- Name += MO.getSymbolName();
-
- O << (isMemOp ? '&' : '#') << Name;
-
+ O << (isMemOp ? '&' : '#');
+ O << MAI->getGlobalPrefix() << MO.getSymbolName();
return;
}
default:
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp b/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
index 0a403c4..a480307 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
+++ b/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
@@ -39,7 +39,7 @@ void MSP430InstPrinter::printPCRelImmOperand(const MCInst *MI, unsigned OpNo) {
O << Op.getImm();
else {
assert(Op.isExpr() && "unknown pcrel immediate operand");
- Op.getExpr()->print(O, &MAI);
+ O << *Op.getExpr();
}
}
@@ -53,8 +53,7 @@ void MSP430InstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
O << '#' << Op.getImm();
} else {
assert(Op.isExpr() && "unknown operand kind in printOperand");
- O << '#';
- Op.getExpr()->print(O, &MAI);
+ O << '#' << *Op.getExpr();
}
}
@@ -65,8 +64,7 @@ void MSP430InstPrinter::printSrcMemOperand(const MCInst *MI, unsigned OpNo,
// Print displacement first
if (Disp.isExpr()) {
- O << '&';
- Disp.getExpr()->print(O, &MAI);
+ O << '&' << *Disp.getExpr();
} else {
assert(Disp.isImm() && "Expected immediate in displacement field");
if (!Base.getReg())
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp b/lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp
index 595b7e7..e1f80b7 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp
+++ b/lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp
@@ -22,37 +22,27 @@
#include "llvm/MC/MCInst.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/ADT/SmallString.h"
using namespace llvm;
MCSymbol *MSP430MCInstLower::
GetGlobalAddressSymbol(const MachineOperand &MO) const {
- const GlobalValue *GV = MO.getGlobal();
-
- SmallString<128> Name;
- Mang.getNameWithPrefix(Name, GV, false);
-
switch (MO.getTargetFlags()) {
default: llvm_unreachable("Unknown target flag on GV operand");
case 0: break;
}
- return Ctx.GetOrCreateSymbol(Name.str());
+ return Printer.GetGlobalValueSymbol(MO.getGlobal());
}
MCSymbol *MSP430MCInstLower::
GetExternalSymbolSymbol(const MachineOperand &MO) const {
- SmallString<128> Name;
- Name += Printer.MAI->getGlobalPrefix();
- Name += MO.getSymbolName();
-
switch (MO.getTargetFlags()) {
default: assert(0 && "Unknown target flag on GV operand");
case 0: break;
}
- return Ctx.GetOrCreateSymbol(Name.str());
+ return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
}
MCSymbol *MSP430MCInstLower::
diff --git a/lib/Target/MSP430/AsmPrinter/Makefile b/lib/Target/MSP430/AsmPrinter/Makefile
index 4f340c6..c8a44a1 100644
--- a/lib/Target/MSP430/AsmPrinter/Makefile
+++ b/lib/Target/MSP430/AsmPrinter/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMMSP430AsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' MSP430 target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/MSP430/CMakeLists.txt b/lib/Target/MSP430/CMakeLists.txt
index 60e0bb1..29abe46 100644
--- a/lib/Target/MSP430/CMakeLists.txt
+++ b/lib/Target/MSP430/CMakeLists.txt
@@ -11,9 +11,10 @@ tablegen(MSP430GenCallingConv.inc -gen-callingconv)
tablegen(MSP430GenSubtarget.inc -gen-subtarget)
add_llvm_target(MSP430CodeGen
- MSP430InstrInfo.cpp
+ MSP430BranchSelector.cpp
MSP430ISelDAGToDAG.cpp
MSP430ISelLowering.cpp
+ MSP430InstrInfo.cpp
MSP430MCAsmInfo.cpp
MSP430RegisterInfo.cpp
MSP430Subtarget.cpp
diff --git a/lib/Target/MSP430/MSP430.h b/lib/Target/MSP430/MSP430.h
index 1ff178d..e742118 100644
--- a/lib/Target/MSP430/MSP430.h
+++ b/lib/Target/MSP430/MSP430.h
@@ -39,6 +39,8 @@ namespace llvm {
FunctionPass *createMSP430ISelDag(MSP430TargetMachine &TM,
CodeGenOpt::Level OptLevel);
+ FunctionPass *createMSP430BranchSelectionPass();
+
extern Target TheMSP430Target;
} // end namespace llvm;
diff --git a/lib/Target/MSP430/MSP430.td b/lib/Target/MSP430/MSP430.td
index 870a3df..fe533d3 100644
--- a/lib/Target/MSP430/MSP430.td
+++ b/lib/Target/MSP430/MSP430.td
@@ -48,8 +48,14 @@ include "MSP430CallingConv.td"
include "MSP430InstrInfo.td"
-def MSP430InstrInfo : InstrInfo {}
-
+def MSP430InstrInfo : InstrInfo {
+ // Define how we want to layout our TargetSpecific information field... This
+ // should be kept up-to-date with the fields in the MSP430InstrInfo.h file.
+ let TSFlagsFields = ["FormBits",
+ "Size"];
+ let TSFlagsShifts = [0,
+ 2];
+}
def MSP430InstPrinter : AsmWriter {
string AsmWriterClassName = "InstPrinter";
diff --git a/lib/Target/MSP430/MSP430BranchSelector.cpp b/lib/Target/MSP430/MSP430BranchSelector.cpp
new file mode 100644
index 0000000..836e425
--- /dev/null
+++ b/lib/Target/MSP430/MSP430BranchSelector.cpp
@@ -0,0 +1,179 @@
+//===-- MSP430BranchSelector.cpp - Emit long conditional branches--*- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a pass that scans a machine function to determine which
+// conditional branches need more than 10 bits of displacement to reach their
+// target basic block. It does this in two passes; a calculation of basic block
+// positions pass, and a branch psuedo op to machine branch opcode pass. This
+// pass should be run last, just before the assembly printer.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "msp430-branch-select"
+#include "MSP430.h"
+#include "MSP430InstrInfo.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/MathExtras.h"
+using namespace llvm;
+
+STATISTIC(NumExpanded, "Number of branches expanded to long format");
+
+namespace {
+ struct MSP430BSel : public MachineFunctionPass {
+ static char ID;
+ MSP430BSel() : MachineFunctionPass(&ID) {}
+
+ /// BlockSizes - The sizes of the basic blocks in the function.
+ std::vector<unsigned> BlockSizes;
+
+ virtual bool runOnMachineFunction(MachineFunction &Fn);
+
+ virtual const char *getPassName() const {
+ return "MSP430 Branch Selector";
+ }
+ };
+ char MSP430BSel::ID = 0;
+}
+
+/// createMSP430BranchSelectionPass - returns an instance of the Branch
+/// Selection Pass
+///
+FunctionPass *llvm::createMSP430BranchSelectionPass() {
+ return new MSP430BSel();
+}
+
+bool MSP430BSel::runOnMachineFunction(MachineFunction &Fn) {
+ const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo();
+ // Give the blocks of the function a dense, in-order, numbering.
+ Fn.RenumberBlocks();
+ BlockSizes.resize(Fn.getNumBlockIDs());
+
+ // Measure each MBB and compute a size for the entire function.
+ unsigned FuncSize = 0;
+ for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
+ ++MFI) {
+ MachineBasicBlock *MBB = MFI;
+
+ unsigned BlockSize = 0;
+ for (MachineBasicBlock::iterator MBBI = MBB->begin(), EE = MBB->end();
+ MBBI != EE; ++MBBI)
+ BlockSize += TII->GetInstSizeInBytes(MBBI);
+
+ BlockSizes[MBB->getNumber()] = BlockSize;
+ FuncSize += BlockSize;
+ }
+
+ // If the entire function is smaller than the displacement of a branch field,
+ // we know we don't need to shrink any branches in this function. This is a
+ // common case.
+ if (FuncSize < (1 << 9)) {
+ BlockSizes.clear();
+ return false;
+ }
+
+ // For each conditional branch, if the offset to its destination is larger
+ // than the offset field allows, transform it into a long branch sequence
+ // like this:
+ // short branch:
+ // bCC MBB
+ // long branch:
+ // b!CC $PC+6
+ // b MBB
+ //
+ bool MadeChange = true;
+ bool EverMadeChange = false;
+ while (MadeChange) {
+ // Iteratively expand branches until we reach a fixed point.
+ MadeChange = false;
+
+ for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
+ ++MFI) {
+ MachineBasicBlock &MBB = *MFI;
+ unsigned MBBStartOffset = 0;
+ for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
+ I != E; ++I) {
+ if ((I->getOpcode() != MSP430::JCC || I->getOperand(0).isImm()) &&
+ I->getOpcode() != MSP430::JMP) {
+ MBBStartOffset += TII->GetInstSizeInBytes(I);
+ continue;
+ }
+
+ // Determine the offset from the current branch to the destination
+ // block.
+ MachineBasicBlock *Dest = I->getOperand(0).getMBB();
+
+ int BranchSize;
+ if (Dest->getNumber() <= MBB.getNumber()) {
+ // If this is a backwards branch, the delta is the offset from the
+ // start of this block to this branch, plus the sizes of all blocks
+ // from this block to the dest.
+ BranchSize = MBBStartOffset;
+
+ for (unsigned i = Dest->getNumber(), e = MBB.getNumber(); i != e; ++i)
+ BranchSize += BlockSizes[i];
+ } else {
+ // Otherwise, add the size of the blocks between this block and the
+ // dest to the number of bytes left in this block.
+ BranchSize = -MBBStartOffset;
+
+ for (unsigned i = MBB.getNumber(), e = Dest->getNumber(); i != e; ++i)
+ BranchSize += BlockSizes[i];
+ }
+
+ // If this branch is in range, ignore it.
+ if (isInt<10>(BranchSize)) {
+ MBBStartOffset += 2;
+ continue;
+ }
+
+ // Otherwise, we have to expand it to a long branch.
+ unsigned NewSize;
+ MachineInstr *OldBranch = I;
+ DebugLoc dl = OldBranch->getDebugLoc();
+
+ if (I->getOpcode() == MSP430::JMP) {
+ NewSize = 4;
+ } else {
+ // The BCC operands are:
+ // 0. MSP430 branch predicate
+ // 1. Target MBB
+ SmallVector<MachineOperand, 1> Cond;
+ Cond.push_back(I->getOperand(1));
+
+ // Jump over the uncond branch inst (i.e. $+6) on opposite condition.
+ TII->ReverseBranchCondition(Cond);
+ BuildMI(MBB, I, dl, TII->get(MSP430::JCC))
+ .addImm(4).addOperand(Cond[0]);
+
+ NewSize = 6;
+ }
+ // Uncond branch to the real destination.
+ I = BuildMI(MBB, I, dl, TII->get(MSP430::B)).addMBB(Dest);
+
+ // Remove the old branch from the function.
+ OldBranch->eraseFromParent();
+
+ // Remember that this instruction is NewSize bytes, increase the size of the
+ // block by NewSize-2, remember to iterate.
+ BlockSizes[MBB.getNumber()] += NewSize-2;
+ MBBStartOffset += NewSize;
+
+ ++NumExpanded;
+ MadeChange = true;
+ }
+ }
+ EverMadeChange |= MadeChange;
+ }
+
+ BlockSizes.clear();
+ return true;
+}
diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp
index d3dce4b..b794911 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -675,21 +675,53 @@ static SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC,
case ISD::SETULE:
std::swap(LHS, RHS); // FALLTHROUGH
case ISD::SETUGE:
+ // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to
+ // fold constant into instruction.
+ if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
+ LHS = RHS;
+ RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
+ TCC = MSP430CC::COND_LO;
+ break;
+ }
TCC = MSP430CC::COND_HS; // aka COND_C
break;
case ISD::SETUGT:
std::swap(LHS, RHS); // FALLTHROUGH
case ISD::SETULT:
+ // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to
+ // fold constant into instruction.
+ if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
+ LHS = RHS;
+ RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
+ TCC = MSP430CC::COND_HS;
+ break;
+ }
TCC = MSP430CC::COND_LO; // aka COND_NC
break;
case ISD::SETLE:
std::swap(LHS, RHS); // FALLTHROUGH
case ISD::SETGE:
+ // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to
+ // fold constant into instruction.
+ if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
+ LHS = RHS;
+ RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
+ TCC = MSP430CC::COND_L;
+ break;
+ }
TCC = MSP430CC::COND_GE;
break;
case ISD::SETGT:
std::swap(LHS, RHS); // FALLTHROUGH
case ISD::SETLT:
+ // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to
+ // fold constant into instruction.
+ if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
+ LHS = RHS;
+ RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
+ TCC = MSP430CC::COND_GE;
+ break;
+ }
TCC = MSP430CC::COND_L;
break;
}
@@ -723,6 +755,8 @@ SDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
// If we are doing an AND and testing against zero, then the CMP
// will not be generated. The AND (or BIT) will generate the condition codes,
// but they are different from CMP.
+ // FIXME: since we're doing a post-processing, use a pseudoinstr here, so
+ // lowering & isel wouldn't diverge.
bool andCC = false;
if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
if (RHSC->isNullValue() && LHS.hasOneUse() &&
@@ -750,11 +784,11 @@ SDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
case MSP430CC::COND_HS:
// Res = SRW & 1, no processing is required
break;
- case MSP430CC::COND_LO:
+ case MSP430CC::COND_LO:
// Res = ~(SRW & 1)
Invert = true;
break;
- case MSP430CC::COND_NE:
+ case MSP430CC::COND_NE:
if (andCC) {
// C = ~Z, thus Res = SRW & 1, no processing is required
} else {
@@ -762,7 +796,7 @@ SDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
Shift = true;
}
break;
- case MSP430CC::COND_E:
+ case MSP430CC::COND_E:
if (andCC) {
// C = ~Z, thus Res = ~(SRW & 1)
} else {
@@ -776,7 +810,7 @@ SDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
SDValue One = DAG.getConstant(1, VT);
if (Convert) {
SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW,
- MVT::i16, Flag);
+ MVT::i16, Flag);
if (Shift)
// FIXME: somewhere this is turned into a SRL, lower it MSP specific?
SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One);
@@ -933,6 +967,31 @@ const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
}
}
+bool MSP430TargetLowering::isTruncateFree(const Type *Ty1,
+ const Type *Ty2) const {
+ if (!Ty1->isInteger() || !Ty2->isInteger())
+ return false;
+
+ return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits());
+}
+
+bool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
+ if (!VT1.isInteger() || !VT2.isInteger())
+ return false;
+
+ return (VT1.getSizeInBits() > VT2.getSizeInBits());
+}
+
+bool MSP430TargetLowering::isZExtFree(const Type *Ty1, const Type *Ty2) const {
+ // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
+ return 0 && Ty1->isInteger(8) && Ty2->isInteger(16);
+}
+
+bool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
+ // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
+ return 0 && VT1 == MVT::i8 && VT2 == MVT::i16;
+}
+
//===----------------------------------------------------------------------===//
// Other Lowering Code
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/MSP430/MSP430ISelLowering.h b/lib/Target/MSP430/MSP430ISelLowering.h
index 4921500..6152a05 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.h
+++ b/lib/Target/MSP430/MSP430ISelLowering.h
@@ -99,6 +99,23 @@ namespace llvm {
std::pair<unsigned, const TargetRegisterClass*>
getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const;
+ /// isTruncateFree - Return true if it's free to truncate a value of type
+ /// Ty1 to type Ty2. e.g. On msp430 it's free to truncate a i16 value in
+ /// register R15W to i8 by referencing its sub-register R15B.
+ virtual bool isTruncateFree(const Type *Ty1, const Type *Ty2) const;
+ virtual bool isTruncateFree(EVT VT1, EVT VT2) const;
+
+ /// isZExtFree - Return true if any actual instruction that defines a value
+ /// of type Ty1 implicit zero-extends the value to Ty2 in the result
+ /// register. This does not necessarily include registers defined in unknown
+ /// ways, such as incoming arguments, or copies from unknown virtual
+ /// registers. Also, if isTruncateFree(Ty2, Ty1) is true, this does not
+ /// necessarily apply to truncate instructions. e.g. on msp430, all
+ /// instructions that define 8-bit values implicit zero-extend the result
+ /// out to 16 bits.
+ virtual bool isZExtFree(const Type *Ty1, const Type *Ty2) const;
+ virtual bool isZExtFree(EVT VT1, EVT VT2) const;
+
MachineBasicBlock* EmitInstrWithCustomInserter(MachineInstr *MI,
MachineBasicBlock *BB,
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const;
diff --git a/lib/Target/MSP430/MSP430InstrFormats.td b/lib/Target/MSP430/MSP430InstrFormats.td
index 61b3399..4ccc7df 100644
--- a/lib/Target/MSP430/MSP430InstrFormats.td
+++ b/lib/Target/MSP430/MSP430InstrFormats.td
@@ -11,8 +11,48 @@
// Describe MSP430 instructions format here
//
+// Format specifies the encoding used by the instruction. This is part of the
+// ad-hoc solution used to emit machine instruction encodings by our machine
+// code emitter.
+class Format<bits<2> val> {
+ bits<2> Value = val;
+}
+
+def PseudoFrm : Format<0>;
+def SingleOpFrm : Format<1>;
+def DoubleOpFrm : Format<2>;
+def CondJumpFrm : Format<3>;
+
+class SourceMode<bits<2> val> {
+ bits<2> Value = val;
+}
+
+def SrcReg : SourceMode<0>;
+def SrcMem : SourceMode<1>;
+def SrcIndReg : SourceMode<2>;
+def SrcPostInc : SourceMode<3>;
+def SrcImm : SourceMode<3>;
+
+class DestMode<bit val> {
+ bit Value = val;
+}
+
+def DstReg : DestMode<0>;
+def DstMem : DestMode<1>;
+
+class SizeVal<bits<3> val> {
+ bits<3> Value = val;
+}
+
+def SizeUnknown : SizeVal<0>; // Unknown / unset size
+def SizeSpecial : SizeVal<1>; // Special instruction, e.g. pseudo
+def Size2Bytes : SizeVal<2>;
+def Size4Bytes : SizeVal<3>;
+def Size6Bytes : SizeVal<4>;
+
// Generic MSP430 Format
-class MSP430Inst<dag outs, dag ins, string asmstr> : Instruction {
+class MSP430Inst<dag outs, dag ins, SizeVal sz, Format f,
+ string asmstr> : Instruction {
field bits<16> Inst;
let Namespace = "MSP430";
@@ -20,48 +60,150 @@ class MSP430Inst<dag outs, dag ins, string asmstr> : Instruction {
dag OutOperandList = outs;
dag InOperandList = ins;
+ Format Form = f;
+ bits<2> FormBits = Form.Value;
+
+ SizeVal Sz = sz;
+ bits<3> Size = Sz.Value;
+
let AsmString = asmstr;
}
// FIXME: Create different classes for different addressing modes.
// MSP430 Double Operand (Format I) Instructions
-class IForm<bits<4> opcode, bit ad, bit bw, bits<2> as,
+class IForm<bits<4> opcode, DestMode dest, bit bw, SourceMode src, SizeVal sz,
dag outs, dag ins, string asmstr, list<dag> pattern>
- : MSP430Inst<outs, ins, asmstr> {
+ : MSP430Inst<outs, ins, sz, DoubleOpFrm, asmstr> {
let Pattern = pattern;
+
+ DestMode ad = dest;
+ SourceMode as = src;
let Inst{12-15} = opcode;
- let Inst{7} = ad;
+ let Inst{7} = ad.Value;
let Inst{6} = bw;
- let Inst{4-5} = as;
+ let Inst{4-5} = as.Value;
}
+// 8 bit IForm instructions
+class IForm8<bits<4> opcode, DestMode dest, SourceMode src, SizeVal sz,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm<opcode, dest, 1, src, sz, outs, ins, asmstr, pattern>;
+
+class I8rr<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm8<opcode, DstReg, SrcReg, Size2Bytes, outs, ins, asmstr, pattern>;
+
+class I8ri<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm8<opcode, DstReg, SrcImm, Size4Bytes, outs, ins, asmstr, pattern>;
+
+class I8rm<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm8<opcode, DstReg, SrcMem, Size4Bytes, outs, ins, asmstr, pattern>;
+
+class I8mr<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm8<opcode, DstMem, SrcReg, Size4Bytes, outs, ins, asmstr, pattern>;
+
+class I8mi<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm8<opcode, DstMem, SrcImm, Size6Bytes, outs, ins, asmstr, pattern>;
+
+class I8mm<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm8<opcode, DstMem, SrcMem, Size6Bytes, outs, ins, asmstr, pattern>;
+
+// 16 bit IForm instructions
+class IForm16<bits<4> opcode, DestMode dest, SourceMode src, SizeVal sz,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm<opcode, dest, 0, src, sz, outs, ins, asmstr, pattern>;
+
+class I16rr<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm16<opcode, DstReg, SrcReg, Size2Bytes, outs, ins, asmstr, pattern>;
+
+class I16ri<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm16<opcode, DstReg, SrcImm, Size4Bytes, outs, ins, asmstr, pattern>;
+
+class I16rm<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm16<opcode, DstReg, SrcMem, Size4Bytes, outs, ins, asmstr, pattern>;
+
+class I16mr<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm16<opcode, DstMem, SrcReg, Size4Bytes, outs, ins, asmstr, pattern>;
+
+class I16mi<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm16<opcode, DstMem, SrcImm, Size6Bytes, outs, ins, asmstr, pattern>;
+
+class I16mm<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm16<opcode, DstMem, SrcMem, Size6Bytes, outs, ins, asmstr, pattern>;
+
// MSP430 Single Operand (Format II) Instructions
-class IIForm<bits<9> opcode, bit bw, bits<2> ad,
+class IIForm<bits<9> opcode, bit bw, SourceMode src, SizeVal sz,
dag outs, dag ins, string asmstr, list<dag> pattern>
- : MSP430Inst<outs, ins, asmstr> {
+ : MSP430Inst<outs, ins, sz, SingleOpFrm, asmstr> {
let Pattern = pattern;
+ SourceMode as = src;
+
let Inst{7-15} = opcode;
let Inst{6} = bw;
- let Inst{4-5} = ad;
+ let Inst{4-5} = as.Value;
}
+// 8 bit IIForm instructions
+class IIForm8<bits<9> opcode, SourceMode src, SizeVal sz,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IIForm<opcode, 1, src, sz, outs, ins, asmstr, pattern>;
+
+class II8r<bits<9> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IIForm8<opcode, SrcReg, Size2Bytes, outs, ins, asmstr, pattern>;
+
+class II8m<bits<9> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IIForm8<opcode, SrcMem, Size4Bytes, outs, ins, asmstr, pattern>;
+
+class II8i<bits<9> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IIForm8<opcode, SrcImm, Size4Bytes, outs, ins, asmstr, pattern>;
+
+// 16 bit IIForm instructions
+class IIForm16<bits<9> opcode, SourceMode src, SizeVal sz,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IIForm<opcode, 0, src, sz, outs, ins, asmstr, pattern>;
+
+class II16r<bits<9> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IIForm16<opcode, SrcReg, Size2Bytes, outs, ins, asmstr, pattern>;
+
+class II16m<bits<9> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IIForm16<opcode, SrcMem, Size4Bytes, outs, ins, asmstr, pattern>;
+
+class II16i<bits<9> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IIForm16<opcode, SrcImm, Size4Bytes, outs, ins, asmstr, pattern>;
+
// MSP430 Conditional Jumps Instructions
-class CJForm<bits<3> opcode, bits<3> cond, bit s,
+class CJForm<bits<3> opcode, bits<3> cond,
dag outs, dag ins, string asmstr, list<dag> pattern>
- : MSP430Inst<outs, ins, asmstr> {
+ : MSP430Inst<outs, ins, Size2Bytes, CondJumpFrm, asmstr> {
let Pattern = pattern;
let Inst{13-15} = opcode;
let Inst{10-12} = cond;
- let Inst{9} = s;
}
// Pseudo instructions
class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
- : MSP430Inst<outs, ins, asmstr> {
+ : MSP430Inst<outs, ins, SizeSpecial, PseudoFrm, asmstr> {
let Pattern = pattern;
let Inst{15-0} = 0;
}
diff --git a/lib/Target/MSP430/MSP430InstrInfo.cpp b/lib/Target/MSP430/MSP430InstrInfo.cpp
index 2ae6759..9dc69e0 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.cpp
+++ b/lib/Target/MSP430/MSP430InstrInfo.cpp
@@ -344,3 +344,45 @@ MSP430InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
}
return Count;
}
+
+/// GetInstSize - Return the number of bytes of code the specified
+/// instruction may be. This returns the maximum number of bytes.
+///
+unsigned MSP430InstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
+ const TargetInstrDesc &Desc = MI->getDesc();
+
+ switch (Desc.TSFlags & MSP430II::SizeMask) {
+ default:
+ switch (Desc.getOpcode()) {
+ default:
+ assert(0 && "Unknown instruction size!");
+ case TargetInstrInfo::DBG_LABEL:
+ case TargetInstrInfo::EH_LABEL:
+ case TargetInstrInfo::IMPLICIT_DEF:
+ case TargetInstrInfo::KILL:
+ return 0;
+ case TargetInstrInfo::INLINEASM: {
+ const MachineFunction *MF = MI->getParent()->getParent();
+ const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
+ return TII.getInlineAsmLength(MI->getOperand(0).getSymbolName(),
+ *MF->getTarget().getMCAsmInfo());
+ }
+ }
+ case MSP430II::SizeSpecial:
+ switch (MI->getOpcode()) {
+ default:
+ assert(0 && "Unknown instruction size!");
+ case MSP430::SAR8r1c:
+ case MSP430::SAR16r1c:
+ return 4;
+ }
+ case MSP430II::Size2Bytes:
+ return 2;
+ case MSP430II::Size4Bytes:
+ return 4;
+ case MSP430II::Size6Bytes:
+ return 6;
+ }
+
+ return 6;
+}
diff --git a/lib/Target/MSP430/MSP430InstrInfo.h b/lib/Target/MSP430/MSP430InstrInfo.h
index e4ceeb9..6ef4b0a 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.h
+++ b/lib/Target/MSP430/MSP430InstrInfo.h
@@ -21,6 +21,22 @@ namespace llvm {
class MSP430TargetMachine;
+/// MSP430II - This namespace holds all of the target specific flags that
+/// instruction info tracks.
+///
+namespace MSP430II {
+ enum {
+ SizeShift = 2,
+ SizeMask = 7 << SizeShift,
+
+ SizeUnknown = 0 << SizeShift,
+ SizeSpecial = 1 << SizeShift,
+ Size2Bytes = 2 << SizeShift,
+ Size4Bytes = 3 << SizeShift,
+ Size6Bytes = 4 << SizeShift
+ };
+}
+
class MSP430InstrInfo : public TargetInstrInfoImpl {
const MSP430RegisterInfo RI;
MSP430TargetMachine &TM;
@@ -59,6 +75,8 @@ public:
MachineBasicBlock::iterator MI,
const std::vector<CalleeSavedInfo> &CSI) const;
+ unsigned GetInstSizeInBytes(const MachineInstr *MI) const;
+
// Branch folding goodness
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
bool isUnpredicatedTerminator(const MachineInstr *MI) const;
diff --git a/lib/Target/MSP430/MSP430InstrInfo.td b/lib/Target/MSP430/MSP430InstrInfo.td
index 022d171..cd502cf 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.td
+++ b/lib/Target/MSP430/MSP430InstrInfo.td
@@ -157,23 +157,35 @@ def NOP : Pseudo<(outs), (ins), "nop", []>;
// FIXME: Provide proper encoding!
let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
- def RET : Pseudo<(outs), (ins), "ret", [(MSP430retflag)]>;
- def RETI : Pseudo<(outs), (ins), "reti", [(MSP430retiflag)]>;
+ def RET : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs), (ins), "ret", [(MSP430retflag)]>;
+ def RETI : II16r<0x0, (outs), (ins), "reti", [(MSP430retiflag)]>;
}
let isBranch = 1, isTerminator = 1 in {
+// FIXME: expand opcode & cond field for branches!
+
// Direct branch
-let isBarrier = 1 in
- def JMP : Pseudo<(outs), (ins brtarget:$dst),
+let isBarrier = 1 in {
+ // Short branch
+ def JMP : CJForm<0, 0,
+ (outs), (ins brtarget:$dst),
"jmp\t$dst",
[(br bb:$dst)]>;
+ // Long branch
+ def B : I16ri<0,
+ (outs), (ins brtarget:$dst),
+ "br\t$dst",
+ []>;
+}
// Conditional branches
let Uses = [SRW] in
- def JCC : Pseudo<(outs), (ins brtarget:$dst, cc:$cc),
- "j$cc\t$dst",
- [(MSP430brcc bb:$dst, imm:$cc)]>;
+ def JCC : CJForm<0, 0,
+ (outs), (ins brtarget:$dst, cc:$cc),
+ "j$cc\t$dst",
+ [(MSP430brcc bb:$dst, imm:$cc)]>;
} // isBranch, isTerminator
//===----------------------------------------------------------------------===//
@@ -186,12 +198,15 @@ let isCall = 1 in
// registers are added manually.
let Defs = [R12W, R13W, R14W, R15W, SRW],
Uses = [SPW] in {
- def CALLi : Pseudo<(outs), (ins i16imm:$dst, variable_ops),
- "call\t$dst", [(MSP430call imm:$dst)]>;
- def CALLr : Pseudo<(outs), (ins GR16:$dst, variable_ops),
- "call\t$dst", [(MSP430call GR16:$dst)]>;
- def CALLm : Pseudo<(outs), (ins memsrc:$dst, variable_ops),
- "call\t${dst:mem}", [(MSP430call (load addr:$dst))]>;
+ def CALLi : II16i<0x0,
+ (outs), (ins i16imm:$dst, variable_ops),
+ "call\t$dst", [(MSP430call imm:$dst)]>;
+ def CALLr : II16r<0x0,
+ (outs), (ins GR16:$dst, variable_ops),
+ "call\t$dst", [(MSP430call GR16:$dst)]>;
+ def CALLm : II16m<0x0,
+ (outs), (ins memsrc:$dst, variable_ops),
+ "call\t${dst:mem}", [(MSP430call (load addr:$dst))]>;
}
@@ -200,10 +215,12 @@ let isCall = 1 in
//
let Defs = [SPW], Uses = [SPW], neverHasSideEffects=1 in {
let mayLoad = 1 in
-def POP16r : Pseudo<(outs GR16:$reg), (ins), "pop.w\t$reg", []>;
+def POP16r : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR16:$reg), (ins), "pop.w\t$reg", []>;
let mayStore = 1 in
-def PUSH16r : Pseudo<(outs), (ins GR16:$reg), "push.w\t$reg",[]>;
+def PUSH16r : II16r<0x0,
+ (outs), (ins GR16:$reg), "push.w\t$reg",[]>;
}
//===----------------------------------------------------------------------===//
@@ -211,45 +228,55 @@ def PUSH16r : Pseudo<(outs), (ins GR16:$reg), "push.w\t$reg",[]>;
// FIXME: Provide proper encoding!
let neverHasSideEffects = 1 in {
-def MOV8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src),
- "mov.b\t{$src, $dst}",
- []>;
-def MOV16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src),
- "mov.w\t{$src, $dst}",
- []>;
+def MOV8rr : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src),
+ "mov.b\t{$src, $dst}",
+ []>;
+def MOV16rr : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src),
+ "mov.w\t{$src, $dst}",
+ []>;
}
// FIXME: Provide proper encoding!
let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
-def MOV8ri : Pseudo<(outs GR8:$dst), (ins i8imm:$src),
- "mov.b\t{$src, $dst}",
- [(set GR8:$dst, imm:$src)]>;
-def MOV16ri : Pseudo<(outs GR16:$dst), (ins i16imm:$src),
- "mov.w\t{$src, $dst}",
- [(set GR16:$dst, imm:$src)]>;
+def MOV8ri : I8ri<0x0,
+ (outs GR8:$dst), (ins i8imm:$src),
+ "mov.b\t{$src, $dst}",
+ [(set GR8:$dst, imm:$src)]>;
+def MOV16ri : I16ri<0x0,
+ (outs GR16:$dst), (ins i16imm:$src),
+ "mov.w\t{$src, $dst}",
+ [(set GR16:$dst, imm:$src)]>;
}
let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
-def MOV8rm : Pseudo<(outs GR8:$dst), (ins memsrc:$src),
- "mov.b\t{$src, $dst}",
- [(set GR8:$dst, (load addr:$src))]>;
-def MOV16rm : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
- "mov.w\t{$src, $dst}",
- [(set GR16:$dst, (load addr:$src))]>;
+def MOV8rm : I8rm<0x0,
+ (outs GR8:$dst), (ins memsrc:$src),
+ "mov.b\t{$src, $dst}",
+ [(set GR8:$dst, (load addr:$src))]>;
+def MOV16rm : I16rm<0x0,
+ (outs GR16:$dst), (ins memsrc:$src),
+ "mov.w\t{$src, $dst}",
+ [(set GR16:$dst, (load addr:$src))]>;
}
-def MOVZX16rr8 : Pseudo<(outs GR16:$dst), (ins GR8:$src),
- "mov.b\t{$src, $dst}",
- [(set GR16:$dst, (zext GR8:$src))]>;
-def MOVZX16rm8 : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
- "mov.b\t{$src, $dst}",
- [(set GR16:$dst, (zextloadi16i8 addr:$src))]>;
+def MOVZX16rr8 : I8rr<0x0,
+ (outs GR16:$dst), (ins GR8:$src),
+ "mov.b\t{$src, $dst}",
+ [(set GR16:$dst, (zext GR8:$src))]>;
+def MOVZX16rm8 : I8rm<0x0,
+ (outs GR16:$dst), (ins memsrc:$src),
+ "mov.b\t{$src, $dst}",
+ [(set GR16:$dst, (zextloadi16i8 addr:$src))]>;
let mayLoad = 1, hasExtraDefRegAllocReq = 1, Constraints = "$base = $base_wb" in {
-def MOV8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR16:$base),
- "mov.b\t{@$base+, $dst}", []>;
-def MOV16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$base),
- "mov.w\t{@$base+, $dst}", []>;
+def MOV8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR8:$dst, GR16:$base_wb), (ins GR16:$base),
+ "mov.b\t{@$base+, $dst}", []>;
+def MOV16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR16:$dst, GR16:$base_wb), (ins GR16:$base),
+ "mov.w\t{@$base+, $dst}", []>;
}
// Any instruction that defines a 8-bit result leaves the high half of the
@@ -267,27 +294,32 @@ def def8 : PatLeaf<(i8 GR8:$src), [{
def : Pat<(i16 (zext def8:$src)),
(SUBREG_TO_REG (i16 0), GR8:$src, subreg_8bit)>;
-
-def MOV8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
- "mov.b\t{$src, $dst}",
- [(store (i8 imm:$src), addr:$dst)]>;
-def MOV16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
- "mov.w\t{$src, $dst}",
- [(store (i16 imm:$src), addr:$dst)]>;
-
-def MOV8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
- "mov.b\t{$src, $dst}",
- [(store GR8:$src, addr:$dst)]>;
-def MOV16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
- "mov.w\t{$src, $dst}",
- [(store GR16:$src, addr:$dst)]>;
-
-def MOV8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "mov.b\t{$src, $dst}",
- [(store (i8 (load addr:$src)), addr:$dst)]>;
-def MOV16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "mov.w\t{$src, $dst}",
- [(store (i16 (load addr:$src)), addr:$dst)]>;
+def MOV8mi : I8mi<0x0,
+ (outs), (ins memdst:$dst, i8imm:$src),
+ "mov.b\t{$src, $dst}",
+ [(store (i8 imm:$src), addr:$dst)]>;
+def MOV16mi : I16mi<0x0,
+ (outs), (ins memdst:$dst, i16imm:$src),
+ "mov.w\t{$src, $dst}",
+ [(store (i16 imm:$src), addr:$dst)]>;
+
+def MOV8mr : I8mr<0x0,
+ (outs), (ins memdst:$dst, GR8:$src),
+ "mov.b\t{$src, $dst}",
+ [(store GR8:$src, addr:$dst)]>;
+def MOV16mr : I16mr<0x0,
+ (outs), (ins memdst:$dst, GR16:$src),
+ "mov.w\t{$src, $dst}",
+ [(store GR16:$src, addr:$dst)]>;
+
+def MOV8mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "mov.b\t{$src, $dst}",
+ [(store (i8 (load addr:$src)), addr:$dst)]>;
+def MOV16mm : I16mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "mov.w\t{$src, $dst}",
+ [(store (i16 (load addr:$src)), addr:$dst)]>;
//===----------------------------------------------------------------------===//
// Arithmetic Instructions
@@ -297,496 +329,624 @@ let isTwoAddress = 1 in {
let Defs = [SRW] in {
let isCommutable = 1 in { // X = ADD Y, Z == X = ADD Z, Y
-// FIXME: Provide proper encoding!
-def ADD8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
- "add.b\t{$src2, $dst}",
- [(set GR8:$dst, (add GR8:$src1, GR8:$src2)),
- (implicit SRW)]>;
-def ADD16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
- "add.w\t{$src2, $dst}",
- [(set GR16:$dst, (add GR16:$src1, GR16:$src2)),
- (implicit SRW)]>;
+
+def ADD8rr : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
+ "add.b\t{$src2, $dst}",
+ [(set GR8:$dst, (add GR8:$src1, GR8:$src2)),
+ (implicit SRW)]>;
+def ADD16rr : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
+ "add.w\t{$src2, $dst}",
+ [(set GR16:$dst, (add GR16:$src1, GR16:$src2)),
+ (implicit SRW)]>;
}
-def ADD8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
- "add.b\t{$src2, $dst}",
- [(set GR8:$dst, (add GR8:$src1, (load addr:$src2))),
- (implicit SRW)]>;
-def ADD16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
- "add.w\t{$src2, $dst}",
- [(set GR16:$dst, (add GR16:$src1, (load addr:$src2))),
- (implicit SRW)]>;
+def ADD8rm : I8rm<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
+ "add.b\t{$src2, $dst}",
+ [(set GR8:$dst, (add GR8:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
+def ADD16rm : I16rm<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
+ "add.w\t{$src2, $dst}",
+ [(set GR16:$dst, (add GR16:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
let mayLoad = 1, hasExtraDefRegAllocReq = 1,
Constraints = "$base = $base_wb, $src1 = $dst" in {
-def ADD8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
- "add.b\t{@$base+, $dst}", []>;
-def ADD16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
+def ADD8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR8:$dst, GR16:$base_wb),
+ (ins GR8:$src1, GR16:$base),
+ "add.b\t{@$base+, $dst}", []>;
+def ADD16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR16:$dst, GR16:$base_wb),
+ (ins GR16:$src1, GR16:$base),
"add.w\t{@$base+, $dst}", []>;
}
-def ADD8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
- "add.b\t{$src2, $dst}",
- [(set GR8:$dst, (add GR8:$src1, imm:$src2)),
- (implicit SRW)]>;
-def ADD16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
- "add.w\t{$src2, $dst}",
- [(set GR16:$dst, (add GR16:$src1, imm:$src2)),
- (implicit SRW)]>;
+def ADD8ri : I8ri<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
+ "add.b\t{$src2, $dst}",
+ [(set GR8:$dst, (add GR8:$src1, imm:$src2)),
+ (implicit SRW)]>;
+def ADD16ri : I16ri<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
+ "add.w\t{$src2, $dst}",
+ [(set GR16:$dst, (add GR16:$src1, imm:$src2)),
+ (implicit SRW)]>;
let isTwoAddress = 0 in {
-def ADD8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
- "add.b\t{$src, $dst}",
- [(store (add (load addr:$dst), GR8:$src), addr:$dst),
- (implicit SRW)]>;
-def ADD16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
- "add.w\t{$src, $dst}",
- [(store (add (load addr:$dst), GR16:$src), addr:$dst),
- (implicit SRW)]>;
-
-def ADD8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
- "add.b\t{$src, $dst}",
- [(store (add (load addr:$dst), (i8 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-def ADD16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
- "add.w\t{$src, $dst}",
- [(store (add (load addr:$dst), (i16 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-
-def ADD8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "add.b\t{$src, $dst}",
- [(store (add (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
-def ADD16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "add.w\t{$src, $dst}",
- [(store (add (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
+def ADD8mr : I8mr<0x0,
+ (outs), (ins memdst:$dst, GR8:$src),
+ "add.b\t{$src, $dst}",
+ [(store (add (load addr:$dst), GR8:$src), addr:$dst),
+ (implicit SRW)]>;
+def ADD16mr : I16mr<0x0,
+ (outs), (ins memdst:$dst, GR16:$src),
+ "add.w\t{$src, $dst}",
+ [(store (add (load addr:$dst), GR16:$src), addr:$dst),
+ (implicit SRW)]>;
+
+def ADD8mi : I8mi<0x0,
+ (outs), (ins memdst:$dst, i8imm:$src),
+ "add.b\t{$src, $dst}",
+ [(store (add (load addr:$dst), (i8 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+def ADD16mi : I16mi<0x0,
+ (outs), (ins memdst:$dst, i16imm:$src),
+ "add.w\t{$src, $dst}",
+ [(store (add (load addr:$dst), (i16 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+
+def ADD8mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "add.b\t{$src, $dst}",
+ [(store (add (load addr:$dst),
+ (i8 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
+def ADD16mm : I16mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "add.w\t{$src, $dst}",
+ [(store (add (load addr:$dst),
+ (i16 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
}
let Uses = [SRW] in {
let isCommutable = 1 in { // X = ADDC Y, Z == X = ADDC Z, Y
-def ADC8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
- "addc.b\t{$src2, $dst}",
- [(set GR8:$dst, (adde GR8:$src1, GR8:$src2)),
- (implicit SRW)]>;
-def ADC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
- "addc.w\t{$src2, $dst}",
- [(set GR16:$dst, (adde GR16:$src1, GR16:$src2)),
- (implicit SRW)]>;
+def ADC8rr : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
+ "addc.b\t{$src2, $dst}",
+ [(set GR8:$dst, (adde GR8:$src1, GR8:$src2)),
+ (implicit SRW)]>;
+def ADC16rr : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
+ "addc.w\t{$src2, $dst}",
+ [(set GR16:$dst, (adde GR16:$src1, GR16:$src2)),
+ (implicit SRW)]>;
} // isCommutable
-def ADC8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
- "addc.b\t{$src2, $dst}",
- [(set GR8:$dst, (adde GR8:$src1, imm:$src2)),
- (implicit SRW)]>;
-def ADC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
- "addc.w\t{$src2, $dst}",
- [(set GR16:$dst, (adde GR16:$src1, imm:$src2)),
- (implicit SRW)]>;
-
-def ADC8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
- "addc.b\t{$src2, $dst}",
- [(set GR8:$dst, (adde GR8:$src1, (load addr:$src2))),
- (implicit SRW)]>;
-def ADC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
- "addc.w\t{$src2, $dst}",
- [(set GR16:$dst, (adde GR16:$src1, (load addr:$src2))),
- (implicit SRW)]>;
+def ADC8ri : I8ri<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
+ "addc.b\t{$src2, $dst}",
+ [(set GR8:$dst, (adde GR8:$src1, imm:$src2)),
+ (implicit SRW)]>;
+def ADC16ri : I16ri<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
+ "addc.w\t{$src2, $dst}",
+ [(set GR16:$dst, (adde GR16:$src1, imm:$src2)),
+ (implicit SRW)]>;
+
+def ADC8rm : I8rm<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
+ "addc.b\t{$src2, $dst}",
+ [(set GR8:$dst, (adde GR8:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
+def ADC16rm : I16rm<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
+ "addc.w\t{$src2, $dst}",
+ [(set GR16:$dst, (adde GR16:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
let isTwoAddress = 0 in {
-def ADC8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
- "addc.b\t{$src, $dst}",
- [(store (adde (load addr:$dst), GR8:$src), addr:$dst),
- (implicit SRW)]>;
-def ADC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
- "addc.w\t{$src, $dst}",
- [(store (adde (load addr:$dst), GR16:$src), addr:$dst),
- (implicit SRW)]>;
-
-def ADC8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
- "addc.b\t{$src, $dst}",
- [(store (adde (load addr:$dst), (i8 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-def ADC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
- "addc.w\t{$src, $dst}",
- [(store (adde (load addr:$dst), (i16 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-
-def ADC8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "addc.b\t{$src, $dst}",
- [(store (adde (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
-def ADC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "addc.w\t{$src, $dst}",
- [(store (adde (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
+def ADC8mr : I8mr<0x0,
+ (outs), (ins memdst:$dst, GR8:$src),
+ "addc.b\t{$src, $dst}",
+ [(store (adde (load addr:$dst), GR8:$src), addr:$dst),
+ (implicit SRW)]>;
+def ADC16mr : I16mr<0x0,
+ (outs), (ins memdst:$dst, GR16:$src),
+ "addc.w\t{$src, $dst}",
+ [(store (adde (load addr:$dst), GR16:$src), addr:$dst),
+ (implicit SRW)]>;
+
+def ADC8mi : I8mi<0x0,
+ (outs), (ins memdst:$dst, i8imm:$src),
+ "addc.b\t{$src, $dst}",
+ [(store (adde (load addr:$dst), (i8 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+def ADC16mi : I16mi<0x0,
+ (outs), (ins memdst:$dst, i16imm:$src),
+ "addc.w\t{$src, $dst}",
+ [(store (adde (load addr:$dst), (i16 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+
+def ADC8mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "addc.b\t{$src, $dst}",
+ [(store (adde (load addr:$dst),
+ (i8 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
+def ADC16mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "addc.w\t{$src, $dst}",
+ [(store (adde (load addr:$dst),
+ (i16 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
}
} // Uses = [SRW]
let isCommutable = 1 in { // X = AND Y, Z == X = AND Z, Y
-def AND8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
- "and.b\t{$src2, $dst}",
- [(set GR8:$dst, (and GR8:$src1, GR8:$src2)),
- (implicit SRW)]>;
-def AND16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
- "and.w\t{$src2, $dst}",
- [(set GR16:$dst, (and GR16:$src1, GR16:$src2)),
- (implicit SRW)]>;
+def AND8rr : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
+ "and.b\t{$src2, $dst}",
+ [(set GR8:$dst, (and GR8:$src1, GR8:$src2)),
+ (implicit SRW)]>;
+def AND16rr : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
+ "and.w\t{$src2, $dst}",
+ [(set GR16:$dst, (and GR16:$src1, GR16:$src2)),
+ (implicit SRW)]>;
}
-def AND8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
- "and.b\t{$src2, $dst}",
- [(set GR8:$dst, (and GR8:$src1, imm:$src2)),
- (implicit SRW)]>;
-def AND16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
- "and.w\t{$src2, $dst}",
- [(set GR16:$dst, (and GR16:$src1, imm:$src2)),
- (implicit SRW)]>;
-
-def AND8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
- "and.b\t{$src2, $dst}",
- [(set GR8:$dst, (and GR8:$src1, (load addr:$src2))),
- (implicit SRW)]>;
-def AND16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
- "and.w\t{$src2, $dst}",
- [(set GR16:$dst, (and GR16:$src1, (load addr:$src2))),
- (implicit SRW)]>;
+def AND8ri : I8ri<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
+ "and.b\t{$src2, $dst}",
+ [(set GR8:$dst, (and GR8:$src1, imm:$src2)),
+ (implicit SRW)]>;
+def AND16ri : I16ri<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
+ "and.w\t{$src2, $dst}",
+ [(set GR16:$dst, (and GR16:$src1, imm:$src2)),
+ (implicit SRW)]>;
+
+def AND8rm : I8rm<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
+ "and.b\t{$src2, $dst}",
+ [(set GR8:$dst, (and GR8:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
+def AND16rm : I16rm<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
+ "and.w\t{$src2, $dst}",
+ [(set GR16:$dst, (and GR16:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
let mayLoad = 1, hasExtraDefRegAllocReq = 1,
Constraints = "$base = $base_wb, $src1 = $dst" in {
-def AND8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
- "and.b\t{@$base+, $dst}", []>;
-def AND16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
- "and.w\t{@$base+, $dst}", []>;
+def AND8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR8:$dst, GR16:$base_wb),
+ (ins GR8:$src1, GR16:$base),
+ "and.b\t{@$base+, $dst}", []>;
+def AND16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR16:$dst, GR16:$base_wb),
+ (ins GR16:$src1, GR16:$base),
+ "and.w\t{@$base+, $dst}", []>;
}
let isTwoAddress = 0 in {
-def AND8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
- "and.b\t{$src, $dst}",
- [(store (and (load addr:$dst), GR8:$src), addr:$dst),
- (implicit SRW)]>;
-def AND16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
- "and.w\t{$src, $dst}",
- [(store (and (load addr:$dst), GR16:$src), addr:$dst),
- (implicit SRW)]>;
-
-def AND8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
- "and.b\t{$src, $dst}",
- [(store (and (load addr:$dst), (i8 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-def AND16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
- "and.w\t{$src, $dst}",
- [(store (and (load addr:$dst), (i16 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-
-def AND8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "and.b\t{$src, $dst}",
- [(store (and (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
-def AND16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "and.w\t{$src, $dst}",
- [(store (and (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
+def AND8mr : I8mr<0x0,
+ (outs), (ins memdst:$dst, GR8:$src),
+ "and.b\t{$src, $dst}",
+ [(store (and (load addr:$dst), GR8:$src), addr:$dst),
+ (implicit SRW)]>;
+def AND16mr : I16mr<0x0,
+ (outs), (ins memdst:$dst, GR16:$src),
+ "and.w\t{$src, $dst}",
+ [(store (and (load addr:$dst), GR16:$src), addr:$dst),
+ (implicit SRW)]>;
+
+def AND8mi : I8mi<0x0,
+ (outs), (ins memdst:$dst, i8imm:$src),
+ "and.b\t{$src, $dst}",
+ [(store (and (load addr:$dst), (i8 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+def AND16mi : I16mi<0x0,
+ (outs), (ins memdst:$dst, i16imm:$src),
+ "and.w\t{$src, $dst}",
+ [(store (and (load addr:$dst), (i16 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+
+def AND8mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "and.b\t{$src, $dst}",
+ [(store (and (load addr:$dst),
+ (i8 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
+def AND16mm : I16mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "and.w\t{$src, $dst}",
+ [(store (and (load addr:$dst),
+ (i16 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
}
let isCommutable = 1 in { // X = OR Y, Z == X = OR Z, Y
-def OR8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
- "bis.b\t{$src2, $dst}",
- [(set GR8:$dst, (or GR8:$src1, GR8:$src2))]>;
-def OR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
- "bis.w\t{$src2, $dst}",
- [(set GR16:$dst, (or GR16:$src1, GR16:$src2))]>;
+def OR8rr : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
+ "bis.b\t{$src2, $dst}",
+ [(set GR8:$dst, (or GR8:$src1, GR8:$src2))]>;
+def OR16rr : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
+ "bis.w\t{$src2, $dst}",
+ [(set GR16:$dst, (or GR16:$src1, GR16:$src2))]>;
}
-def OR8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
- "bis.b\t{$src2, $dst}",
- [(set GR8:$dst, (or GR8:$src1, imm:$src2))]>;
-def OR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
- "bis.w\t{$src2, $dst}",
- [(set GR16:$dst, (or GR16:$src1, imm:$src2))]>;
-
-def OR8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
- "bis.b\t{$src2, $dst}",
- [(set GR8:$dst, (or GR8:$src1, (load addr:$src2)))]>;
-def OR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
- "bis.w\t{$src2, $dst}",
- [(set GR16:$dst, (or GR16:$src1, (load addr:$src2)))]>;
+def OR8ri : I8ri<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
+ "bis.b\t{$src2, $dst}",
+ [(set GR8:$dst, (or GR8:$src1, imm:$src2))]>;
+def OR16ri : I16ri<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
+ "bis.w\t{$src2, $dst}",
+ [(set GR16:$dst, (or GR16:$src1, imm:$src2))]>;
+
+def OR8rm : I8rm<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
+ "bis.b\t{$src2, $dst}",
+ [(set GR8:$dst, (or GR8:$src1, (load addr:$src2)))]>;
+def OR16rm : I16rm<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
+ "bis.w\t{$src2, $dst}",
+ [(set GR16:$dst, (or GR16:$src1, (load addr:$src2)))]>;
let mayLoad = 1, hasExtraDefRegAllocReq = 1,
Constraints = "$base = $base_wb, $src1 = $dst" in {
-def OR8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
+def OR8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR8:$dst, GR16:$base_wb),
+ (ins GR8:$src1, GR16:$base),
"bis.b\t{@$base+, $dst}", []>;
-def OR16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
- "bis.w\t{@$base+, $dst}", []>;
+def OR16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR16:$dst, GR16:$base_wb),
+ (ins GR16:$src1, GR16:$base),
+ "bis.w\t{@$base+, $dst}", []>;
}
let isTwoAddress = 0 in {
-def OR8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
- "bis.b\t{$src, $dst}",
- [(store (or (load addr:$dst), GR8:$src), addr:$dst)]>;
-def OR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
- "bis.w\t{$src, $dst}",
- [(store (or (load addr:$dst), GR16:$src), addr:$dst)]>;
-
-def OR8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
- "bis.b\t{$src, $dst}",
- [(store (or (load addr:$dst), (i8 imm:$src)), addr:$dst)]>;
-def OR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
- "bis.w\t{$src, $dst}",
- [(store (or (load addr:$dst), (i16 imm:$src)), addr:$dst)]>;
-
-def OR8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "bis.b\t{$src, $dst}",
- [(store (or (i8 (load addr:$dst)),
- (i8 (load addr:$src))), addr:$dst)]>;
-def OR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "bis.w\t{$src, $dst}",
- [(store (or (i16 (load addr:$dst)),
- (i16 (load addr:$src))), addr:$dst)]>;
+def OR8mr : I8mr<0x0,
+ (outs), (ins memdst:$dst, GR8:$src),
+ "bis.b\t{$src, $dst}",
+ [(store (or (load addr:$dst), GR8:$src), addr:$dst)]>;
+def OR16mr : I16mr<0x0,
+ (outs), (ins memdst:$dst, GR16:$src),
+ "bis.w\t{$src, $dst}",
+ [(store (or (load addr:$dst), GR16:$src), addr:$dst)]>;
+
+def OR8mi : I8mi<0x0,
+ (outs), (ins memdst:$dst, i8imm:$src),
+ "bis.b\t{$src, $dst}",
+ [(store (or (load addr:$dst), (i8 imm:$src)), addr:$dst)]>;
+def OR16mi : I16mi<0x0,
+ (outs), (ins memdst:$dst, i16imm:$src),
+ "bis.w\t{$src, $dst}",
+ [(store (or (load addr:$dst), (i16 imm:$src)), addr:$dst)]>;
+
+def OR8mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "bis.b\t{$src, $dst}",
+ [(store (or (i8 (load addr:$dst)),
+ (i8 (load addr:$src))), addr:$dst)]>;
+def OR16mm : I16mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "bis.w\t{$src, $dst}",
+ [(store (or (i16 (load addr:$dst)),
+ (i16 (load addr:$src))), addr:$dst)]>;
}
// bic does not modify condition codes
-def BIC8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
- "bic.b\t{$src2, $dst}",
- [(set GR8:$dst, (and GR8:$src1, (not GR8:$src2)))]>;
-def BIC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
- "bic.w\t{$src2, $dst}",
- [(set GR16:$dst, (and GR16:$src1, (not GR16:$src2)))]>;
-
-def BIC8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
- "bic.b\t{$src2, $dst}",
- [(set GR8:$dst, (and GR8:$src1, (not (i8 (load addr:$src2)))))]>;
-def BIC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
- "bic.w\t{$src2, $dst}",
- [(set GR16:$dst, (and GR16:$src1, (not (i16 (load addr:$src2)))))]>;
+def BIC8rr : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
+ "bic.b\t{$src2, $dst}",
+ [(set GR8:$dst, (and GR8:$src1, (not GR8:$src2)))]>;
+def BIC16rr : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
+ "bic.w\t{$src2, $dst}",
+ [(set GR16:$dst, (and GR16:$src1, (not GR16:$src2)))]>;
+
+def BIC8rm : I8rm<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
+ "bic.b\t{$src2, $dst}",
+ [(set GR8:$dst, (and GR8:$src1, (not (i8 (load addr:$src2)))))]>;
+def BIC16rm : I16rm<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
+ "bic.w\t{$src2, $dst}",
+ [(set GR16:$dst, (and GR16:$src1, (not (i16 (load addr:$src2)))))]>;
let isTwoAddress = 0 in {
-def BIC8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
- "bic.b\t{$src, $dst}",
- [(store (and (load addr:$dst), (not GR8:$src)), addr:$dst)]>;
-def BIC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
- "bic.w\t{$src, $dst}",
- [(store (and (load addr:$dst), (not GR16:$src)), addr:$dst)]>;
-
-def BIC8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "bic.b\t{$src, $dst}",
- [(store (and (load addr:$dst), (not (i8 (load addr:$src)))), addr:$dst)]>;
-def BIC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "bic.w\t{$src, $dst}",
- [(store (and (load addr:$dst), (not (i16 (load addr:$src)))), addr:$dst)]>;
+def BIC8mr : I8mr<0x0,
+ (outs), (ins memdst:$dst, GR8:$src),
+ "bic.b\t{$src, $dst}",
+ [(store (and (load addr:$dst), (not GR8:$src)), addr:$dst)]>;
+def BIC16mr : I16mr<0x0,
+ (outs), (ins memdst:$dst, GR16:$src),
+ "bic.w\t{$src, $dst}",
+ [(store (and (load addr:$dst), (not GR16:$src)), addr:$dst)]>;
+
+def BIC8mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "bic.b\t{$src, $dst}",
+ [(store (and (load addr:$dst),
+ (not (i8 (load addr:$src)))), addr:$dst)]>;
+def BIC16mm : I16mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "bic.w\t{$src, $dst}",
+ [(store (and (load addr:$dst),
+ (not (i16 (load addr:$src)))), addr:$dst)]>;
}
let isCommutable = 1 in { // X = XOR Y, Z == X = XOR Z, Y
-def XOR8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
- "xor.b\t{$src2, $dst}",
- [(set GR8:$dst, (xor GR8:$src1, GR8:$src2)),
- (implicit SRW)]>;
-def XOR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
- "xor.w\t{$src2, $dst}",
- [(set GR16:$dst, (xor GR16:$src1, GR16:$src2)),
- (implicit SRW)]>;
+def XOR8rr : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
+ "xor.b\t{$src2, $dst}",
+ [(set GR8:$dst, (xor GR8:$src1, GR8:$src2)),
+ (implicit SRW)]>;
+def XOR16rr : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
+ "xor.w\t{$src2, $dst}",
+ [(set GR16:$dst, (xor GR16:$src1, GR16:$src2)),
+ (implicit SRW)]>;
}
-def XOR8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
- "xor.b\t{$src2, $dst}",
- [(set GR8:$dst, (xor GR8:$src1, imm:$src2)),
- (implicit SRW)]>;
-def XOR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
- "xor.w\t{$src2, $dst}",
- [(set GR16:$dst, (xor GR16:$src1, imm:$src2)),
- (implicit SRW)]>;
-
-def XOR8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
- "xor.b\t{$src2, $dst}",
- [(set GR8:$dst, (xor GR8:$src1, (load addr:$src2))),
- (implicit SRW)]>;
-def XOR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
- "xor.w\t{$src2, $dst}",
- [(set GR16:$dst, (xor GR16:$src1, (load addr:$src2))),
- (implicit SRW)]>;
+def XOR8ri : I8ri<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
+ "xor.b\t{$src2, $dst}",
+ [(set GR8:$dst, (xor GR8:$src1, imm:$src2)),
+ (implicit SRW)]>;
+def XOR16ri : I16ri<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
+ "xor.w\t{$src2, $dst}",
+ [(set GR16:$dst, (xor GR16:$src1, imm:$src2)),
+ (implicit SRW)]>;
+
+def XOR8rm : I8rm<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
+ "xor.b\t{$src2, $dst}",
+ [(set GR8:$dst, (xor GR8:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
+def XOR16rm : I16rm<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
+ "xor.w\t{$src2, $dst}",
+ [(set GR16:$dst, (xor GR16:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
let mayLoad = 1, hasExtraDefRegAllocReq = 1,
Constraints = "$base = $base_wb, $src1 = $dst" in {
-def XOR8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
- "xor.b\t{@$base+, $dst}", []>;
-def XOR16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
- "xor.w\t{@$base+, $dst}", []>;
+def XOR8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR8:$dst, GR16:$base_wb),
+ (ins GR8:$src1, GR16:$base),
+ "xor.b\t{@$base+, $dst}", []>;
+def XOR16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR16:$dst, GR16:$base_wb),
+ (ins GR16:$src1, GR16:$base),
+ "xor.w\t{@$base+, $dst}", []>;
}
let isTwoAddress = 0 in {
-def XOR8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
- "xor.b\t{$src, $dst}",
- [(store (xor (load addr:$dst), GR8:$src), addr:$dst),
- (implicit SRW)]>;
-def XOR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
- "xor.w\t{$src, $dst}",
- [(store (xor (load addr:$dst), GR16:$src), addr:$dst),
- (implicit SRW)]>;
-
-def XOR8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
- "xor.b\t{$src, $dst}",
- [(store (xor (load addr:$dst), (i8 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-def XOR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
- "xor.w\t{$src, $dst}",
- [(store (xor (load addr:$dst), (i16 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-
-def XOR8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "xor.b\t{$src, $dst}",
- [(store (xor (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
-def XOR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "xor.w\t{$src, $dst}",
- [(store (xor (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
+def XOR8mr : I8mr<0x0,
+ (outs), (ins memdst:$dst, GR8:$src),
+ "xor.b\t{$src, $dst}",
+ [(store (xor (load addr:$dst), GR8:$src), addr:$dst),
+ (implicit SRW)]>;
+def XOR16mr : I16mr<0x0,
+ (outs), (ins memdst:$dst, GR16:$src),
+ "xor.w\t{$src, $dst}",
+ [(store (xor (load addr:$dst), GR16:$src), addr:$dst),
+ (implicit SRW)]>;
+
+def XOR8mi : I8mi<0x0,
+ (outs), (ins memdst:$dst, i8imm:$src),
+ "xor.b\t{$src, $dst}",
+ [(store (xor (load addr:$dst), (i8 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+def XOR16mi : I16mi<0x0,
+ (outs), (ins memdst:$dst, i16imm:$src),
+ "xor.w\t{$src, $dst}",
+ [(store (xor (load addr:$dst), (i16 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+
+def XOR8mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "xor.b\t{$src, $dst}",
+ [(store (xor (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
+def XOR16mm : I16mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "xor.w\t{$src, $dst}",
+ [(store (xor (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
}
-def SUB8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
- "sub.b\t{$src2, $dst}",
- [(set GR8:$dst, (sub GR8:$src1, GR8:$src2)),
- (implicit SRW)]>;
-def SUB16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
- "sub.w\t{$src2, $dst}",
- [(set GR16:$dst, (sub GR16:$src1, GR16:$src2)),
- (implicit SRW)]>;
-
-def SUB8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
- "sub.b\t{$src2, $dst}",
- [(set GR8:$dst, (sub GR8:$src1, imm:$src2)),
- (implicit SRW)]>;
-def SUB16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
- "sub.w\t{$src2, $dst}",
- [(set GR16:$dst, (sub GR16:$src1, imm:$src2)),
- (implicit SRW)]>;
-
-def SUB8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
- "sub.b\t{$src2, $dst}",
- [(set GR8:$dst, (sub GR8:$src1, (load addr:$src2))),
- (implicit SRW)]>;
-def SUB16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
- "sub.w\t{$src2, $dst}",
- [(set GR16:$dst, (sub GR16:$src1, (load addr:$src2))),
- (implicit SRW)]>;
+def SUB8rr : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
+ "sub.b\t{$src2, $dst}",
+ [(set GR8:$dst, (sub GR8:$src1, GR8:$src2)),
+ (implicit SRW)]>;
+def SUB16rr : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
+ "sub.w\t{$src2, $dst}",
+ [(set GR16:$dst, (sub GR16:$src1, GR16:$src2)),
+ (implicit SRW)]>;
+
+def SUB8ri : I8ri<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
+ "sub.b\t{$src2, $dst}",
+ [(set GR8:$dst, (sub GR8:$src1, imm:$src2)),
+ (implicit SRW)]>;
+def SUB16ri : I16ri<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
+ "sub.w\t{$src2, $dst}",
+ [(set GR16:$dst, (sub GR16:$src1, imm:$src2)),
+ (implicit SRW)]>;
+
+def SUB8rm : I8rm<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
+ "sub.b\t{$src2, $dst}",
+ [(set GR8:$dst, (sub GR8:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
+def SUB16rm : I16rm<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
+ "sub.w\t{$src2, $dst}",
+ [(set GR16:$dst, (sub GR16:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
let mayLoad = 1, hasExtraDefRegAllocReq = 1,
Constraints = "$base = $base_wb, $src1 = $dst" in {
-def SUB8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
- "sub.b\t{@$base+, $dst}", []>;
-def SUB16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
+def SUB8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR8:$dst, GR16:$base_wb),
+ (ins GR8:$src1, GR16:$base),
+ "sub.b\t{@$base+, $dst}", []>;
+def SUB16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR16:$dst, GR16:$base_wb),
+ (ins GR16:$src1, GR16:$base),
"sub.w\t{@$base+, $dst}", []>;
}
let isTwoAddress = 0 in {
-def SUB8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
- "sub.b\t{$src, $dst}",
- [(store (sub (load addr:$dst), GR8:$src), addr:$dst),
- (implicit SRW)]>;
-def SUB16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
- "sub.w\t{$src, $dst}",
- [(store (sub (load addr:$dst), GR16:$src), addr:$dst),
- (implicit SRW)]>;
-
-def SUB8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
- "sub.b\t{$src, $dst}",
- [(store (sub (load addr:$dst), (i8 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-def SUB16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
- "sub.w\t{$src, $dst}",
- [(store (sub (load addr:$dst), (i16 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-
-def SUB8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "sub.b\t{$src, $dst}",
- [(store (sub (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
-def SUB16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "sub.w\t{$src, $dst}",
- [(store (sub (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
+def SUB8mr : I8mr<0x0,
+ (outs), (ins memdst:$dst, GR8:$src),
+ "sub.b\t{$src, $dst}",
+ [(store (sub (load addr:$dst), GR8:$src), addr:$dst),
+ (implicit SRW)]>;
+def SUB16mr : I16mr<0x0,
+ (outs), (ins memdst:$dst, GR16:$src),
+ "sub.w\t{$src, $dst}",
+ [(store (sub (load addr:$dst), GR16:$src), addr:$dst),
+ (implicit SRW)]>;
+
+def SUB8mi : I8mi<0x0,
+ (outs), (ins memdst:$dst, i8imm:$src),
+ "sub.b\t{$src, $dst}",
+ [(store (sub (load addr:$dst), (i8 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+def SUB16mi : I16mi<0x0,
+ (outs), (ins memdst:$dst, i16imm:$src),
+ "sub.w\t{$src, $dst}",
+ [(store (sub (load addr:$dst), (i16 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+
+def SUB8mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "sub.b\t{$src, $dst}",
+ [(store (sub (load addr:$dst),
+ (i8 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
+def SUB16mm : I16mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "sub.w\t{$src, $dst}",
+ [(store (sub (load addr:$dst),
+ (i16 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
}
let Uses = [SRW] in {
-def SBC8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
- "subc.b\t{$src2, $dst}",
- [(set GR8:$dst, (sube GR8:$src1, GR8:$src2)),
- (implicit SRW)]>;
-def SBC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
- "subc.w\t{$src2, $dst}",
- [(set GR16:$dst, (sube GR16:$src1, GR16:$src2)),
- (implicit SRW)]>;
-
-def SBC8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
- "subc.b\t{$src2, $dst}",
- [(set GR8:$dst, (sube GR8:$src1, imm:$src2)),
- (implicit SRW)]>;
-def SBC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
- "subc.w\t{$src2, $dst}",
- [(set GR16:$dst, (sube GR16:$src1, imm:$src2)),
- (implicit SRW)]>;
-
-def SBC8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
- "subc.b\t{$src2, $dst}",
- [(set GR8:$dst, (sube GR8:$src1, (load addr:$src2))),
- (implicit SRW)]>;
-def SBC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
- "subc.w\t{$src2, $dst}",
- [(set GR16:$dst, (sube GR16:$src1, (load addr:$src2))),
- (implicit SRW)]>;
+def SBC8rr : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
+ "subc.b\t{$src2, $dst}",
+ [(set GR8:$dst, (sube GR8:$src1, GR8:$src2)),
+ (implicit SRW)]>;
+def SBC16rr : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
+ "subc.w\t{$src2, $dst}",
+ [(set GR16:$dst, (sube GR16:$src1, GR16:$src2)),
+ (implicit SRW)]>;
+
+def SBC8ri : I8ri<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
+ "subc.b\t{$src2, $dst}",
+ [(set GR8:$dst, (sube GR8:$src1, imm:$src2)),
+ (implicit SRW)]>;
+def SBC16ri : I16ri<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
+ "subc.w\t{$src2, $dst}",
+ [(set GR16:$dst, (sube GR16:$src1, imm:$src2)),
+ (implicit SRW)]>;
+
+def SBC8rm : I8rm<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
+ "subc.b\t{$src2, $dst}",
+ [(set GR8:$dst, (sube GR8:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
+def SBC16rm : I16rm<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
+ "subc.w\t{$src2, $dst}",
+ [(set GR16:$dst, (sube GR16:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
let isTwoAddress = 0 in {
-def SBC8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
- "subc.b\t{$src, $dst}",
- [(store (sube (load addr:$dst), GR8:$src), addr:$dst),
- (implicit SRW)]>;
-def SBC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
- "subc.w\t{$src, $dst}",
- [(store (sube (load addr:$dst), GR16:$src), addr:$dst),
- (implicit SRW)]>;
-
-def SBC8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
- "subc.b\t{$src, $dst}",
- [(store (sube (load addr:$dst), (i8 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-def SBC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
- "subc.w\t{$src, $dst}",
- [(store (sube (load addr:$dst), (i16 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-
-def SBC8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "subc.b\t{$src, $dst}",
- [(store (sube (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
-def SBC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "subc.w\t{$src, $dst}",
- [(store (sube (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
+def SBC8mr : I8mr<0x0,
+ (outs), (ins memdst:$dst, GR8:$src),
+ "subc.b\t{$src, $dst}",
+ [(store (sube (load addr:$dst), GR8:$src), addr:$dst),
+ (implicit SRW)]>;
+def SBC16mr : I16mr<0x0,
+ (outs), (ins memdst:$dst, GR16:$src),
+ "subc.w\t{$src, $dst}",
+ [(store (sube (load addr:$dst), GR16:$src), addr:$dst),
+ (implicit SRW)]>;
+
+def SBC8mi : I8mi<0x0,
+ (outs), (ins memdst:$dst, i8imm:$src),
+ "subc.b\t{$src, $dst}",
+ [(store (sube (load addr:$dst), (i8 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+def SBC16mi : I16mi<0x0,
+ (outs), (ins memdst:$dst, i16imm:$src),
+ "subc.w\t{$src, $dst}",
+ [(store (sube (load addr:$dst), (i16 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+
+def SBC8mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "subc.b\t{$src, $dst}",
+ [(store (sube (load addr:$dst),
+ (i8 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
+def SBC16mm : I16mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "subc.w\t{$src, $dst}",
+ [(store (sube (load addr:$dst),
+ (i16 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
}
} // Uses = [SRW]
-// FIXME: Provide proper encoding!
-def SAR8r1 : Pseudo<(outs GR8:$dst), (ins GR8:$src),
- "rra.b\t$dst",
- [(set GR8:$dst, (MSP430rra GR8:$src)),
- (implicit SRW)]>;
-def SAR16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
- "rra.w\t$dst",
- [(set GR16:$dst, (MSP430rra GR16:$src)),
- (implicit SRW)]>;
-
-def SHL8r1 : Pseudo<(outs GR8:$dst), (ins GR8:$src),
- "rla.b\t$dst",
- [(set GR8:$dst, (MSP430rla GR8:$src)),
- (implicit SRW)]>;
-def SHL16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
- "rla.w\t$dst",
- [(set GR16:$dst, (MSP430rla GR16:$src)),
- (implicit SRW)]>;
+// FIXME: memory variant!
+def SAR8r1 : II8r<0x0,
+ (outs GR8:$dst), (ins GR8:$src),
+ "rra.b\t$dst",
+ [(set GR8:$dst, (MSP430rra GR8:$src)),
+ (implicit SRW)]>;
+def SAR16r1 : II16r<0x0,
+ (outs GR16:$dst), (ins GR16:$src),
+ "rra.w\t$dst",
+ [(set GR16:$dst, (MSP430rra GR16:$src)),
+ (implicit SRW)]>;
+
+def SHL8r1 : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src),
+ "rla.b\t$dst",
+ [(set GR8:$dst, (MSP430rla GR8:$src)),
+ (implicit SRW)]>;
+def SHL16r1 : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src),
+ "rla.w\t$dst",
+ [(set GR16:$dst, (MSP430rla GR16:$src)),
+ (implicit SRW)]>;
def SAR8r1c : Pseudo<(outs GR8:$dst), (ins GR8:$src),
"clrc\n\t"
@@ -799,121 +959,154 @@ def SAR16r1c : Pseudo<(outs GR16:$dst), (ins GR16:$src),
[(set GR16:$dst, (MSP430rrc GR16:$src)),
(implicit SRW)]>;
-def SEXT16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
- "sxt\t$dst",
- [(set GR16:$dst, (sext_inreg GR16:$src, i8)),
- (implicit SRW)]>;
+// FIXME: Memory sext's ?
+def SEXT16r : II16r<0x0,
+ (outs GR16:$dst), (ins GR16:$src),
+ "sxt\t$dst",
+ [(set GR16:$dst, (sext_inreg GR16:$src, i8)),
+ (implicit SRW)]>;
} // Defs = [SRW]
-def ZEXT16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
- "mov.b\t{$src, $dst}",
- [(set GR16:$dst, (zext (trunc GR16:$src)))]>;
+def ZEXT16r : I8rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src),
+ "mov.b\t{$src, $dst}",
+ [(set GR16:$dst, (zext (trunc GR16:$src)))]>;
-def SWPB16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
- "swpb\t$dst",
- [(set GR16:$dst, (bswap GR16:$src))]>;
+// FIXME: Memory bitswaps?
+def SWPB16r : II16r<0x0,
+ (outs GR16:$dst), (ins GR16:$src),
+ "swpb\t$dst",
+ [(set GR16:$dst, (bswap GR16:$src))]>;
} // isTwoAddress = 1
// Integer comparisons
let Defs = [SRW] in {
-def CMP8rr : Pseudo<(outs), (ins GR8:$src1, GR8:$src2),
- "cmp.b\t{$src2, $src1}",
- [(MSP430cmp GR8:$src1, GR8:$src2), (implicit SRW)]>;
-def CMP16rr : Pseudo<(outs), (ins GR16:$src1, GR16:$src2),
- "cmp.w\t{$src2, $src1}",
- [(MSP430cmp GR16:$src1, GR16:$src2), (implicit SRW)]>;
-
-def CMP8ri : Pseudo<(outs), (ins GR8:$src1, i8imm:$src2),
+def CMP8rr : I8rr<0x0,
+ (outs), (ins GR8:$src1, GR8:$src2),
+ "cmp.b\t{$src2, $src1}",
+ [(MSP430cmp GR8:$src1, GR8:$src2), (implicit SRW)]>;
+def CMP16rr : I16rr<0x0,
+ (outs), (ins GR16:$src1, GR16:$src2),
+ "cmp.w\t{$src2, $src1}",
+ [(MSP430cmp GR16:$src1, GR16:$src2), (implicit SRW)]>;
+
+def CMP8ri : I8ri<0x0,
+ (outs), (ins GR8:$src1, i8imm:$src2),
"cmp.b\t{$src2, $src1}",
[(MSP430cmp GR8:$src1, imm:$src2), (implicit SRW)]>;
-def CMP16ri : Pseudo<(outs), (ins GR16:$src1, i16imm:$src2),
- "cmp.w\t{$src2, $src1}",
- [(MSP430cmp GR16:$src1, imm:$src2), (implicit SRW)]>;
-
-def CMP8mi : Pseudo<(outs), (ins memsrc:$src1, i8imm:$src2),
- "cmp.b\t{$src2, $src1}",
- [(MSP430cmp (load addr:$src1),
- (i8 imm:$src2)), (implicit SRW)]>;
-def CMP16mi : Pseudo<(outs), (ins memsrc:$src1, i16imm:$src2),
- "cmp.w\t{$src2, $src1}",
- [(MSP430cmp (load addr:$src1),
- (i16 imm:$src2)), (implicit SRW)]>;
-
-def CMP8rm : Pseudo<(outs), (ins GR8:$src1, memsrc:$src2),
- "cmp.b\t{$src2, $src1}",
- [(MSP430cmp GR8:$src1, (load addr:$src2)), (implicit SRW)]>;
-def CMP16rm : Pseudo<(outs), (ins GR16:$src1, memsrc:$src2),
- "cmp.w\t{$src2, $src1}",
- [(MSP430cmp GR16:$src1, (load addr:$src2)), (implicit SRW)]>;
-
-def CMP8mr : Pseudo<(outs), (ins memsrc:$src1, GR8:$src2),
- "cmp.b\t{$src2, $src1}",
- [(MSP430cmp (load addr:$src1), GR8:$src2), (implicit SRW)]>;
-def CMP16mr : Pseudo<(outs), (ins memsrc:$src1, GR16:$src2),
- "cmp.w\t{$src2, $src1}",
- [(MSP430cmp (load addr:$src1), GR16:$src2), (implicit SRW)]>;
+def CMP16ri : I16ri<0x0,
+ (outs), (ins GR16:$src1, i16imm:$src2),
+ "cmp.w\t{$src2, $src1}",
+ [(MSP430cmp GR16:$src1, imm:$src2), (implicit SRW)]>;
+
+def CMP8mi : I8mi<0x0,
+ (outs), (ins memsrc:$src1, i8imm:$src2),
+ "cmp.b\t{$src2, $src1}",
+ [(MSP430cmp (load addr:$src1),
+ (i8 imm:$src2)), (implicit SRW)]>;
+def CMP16mi : I16mi<0x0,
+ (outs), (ins memsrc:$src1, i16imm:$src2),
+ "cmp.w\t{$src2, $src1}",
+ [(MSP430cmp (load addr:$src1),
+ (i16 imm:$src2)), (implicit SRW)]>;
+
+def CMP8rm : I8rm<0x0,
+ (outs), (ins GR8:$src1, memsrc:$src2),
+ "cmp.b\t{$src2, $src1}",
+ [(MSP430cmp GR8:$src1, (load addr:$src2)),
+ (implicit SRW)]>;
+def CMP16rm : I16rm<0x0,
+ (outs), (ins GR16:$src1, memsrc:$src2),
+ "cmp.w\t{$src2, $src1}",
+ [(MSP430cmp GR16:$src1, (load addr:$src2)),
+ (implicit SRW)]>;
+
+def CMP8mr : I8mr<0x0,
+ (outs), (ins memsrc:$src1, GR8:$src2),
+ "cmp.b\t{$src2, $src1}",
+ [(MSP430cmp (load addr:$src1), GR8:$src2),
+ (implicit SRW)]>;
+def CMP16mr : I16mr<0x0,
+ (outs), (ins memsrc:$src1, GR16:$src2),
+ "cmp.w\t{$src2, $src1}",
+ [(MSP430cmp (load addr:$src1), GR16:$src2),
+ (implicit SRW)]>;
// BIT TESTS, just sets condition codes
// Note that the C condition is set differently than when using CMP.
let isCommutable = 1 in {
-def BIT8rr : Pseudo<(outs), (ins GR8:$src1, GR8:$src2),
- "bit.b\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su GR8:$src1, GR8:$src2)),
- (implicit SRW)]>;
-def BIT16rr : Pseudo<(outs), (ins GR16:$src1, GR16:$src2),
- "bit.w\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su GR16:$src1, GR16:$src2)),
- (implicit SRW)]>;
+def BIT8rr : I8rr<0x0,
+ (outs), (ins GR8:$src1, GR8:$src2),
+ "bit.b\t{$src2, $src1}",
+ [(MSP430cmp (and_su GR8:$src1, GR8:$src2), 0),
+ (implicit SRW)]>;
+def BIT16rr : I16rr<0x0,
+ (outs), (ins GR16:$src1, GR16:$src2),
+ "bit.w\t{$src2, $src1}",
+ [(MSP430cmp (and_su GR16:$src1, GR16:$src2), 0),
+ (implicit SRW)]>;
}
-def BIT8ri : Pseudo<(outs), (ins GR8:$src1, i8imm:$src2),
- "bit.b\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su GR8:$src1, imm:$src2)),
- (implicit SRW)]>;
-def BIT16ri : Pseudo<(outs), (ins GR16:$src1, i16imm:$src2),
- "bit.w\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su GR16:$src1, imm:$src2)),
- (implicit SRW)]>;
-
-def BIT8rm : Pseudo<(outs), (ins GR8:$src1, memdst:$src2),
- "bit.b\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su GR8:$src1, (load addr:$src2))),
- (implicit SRW)]>;
-def BIT16rm : Pseudo<(outs), (ins GR16:$src1, memdst:$src2),
- "bit.w\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su GR16:$src1, (load addr:$src2))),
- (implicit SRW)]>;
-
-def BIT8mr : Pseudo<(outs), (ins memsrc:$src1, GR8:$src2),
- "bit.b\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su (load addr:$src1), GR8:$src2)),
- (implicit SRW)]>;
-def BIT16mr : Pseudo<(outs), (ins memsrc:$src1, GR16:$src2),
- "bit.w\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su (load addr:$src1), GR16:$src2)),
- (implicit SRW)]>;
-
-def BIT8mi : Pseudo<(outs), (ins memsrc:$src1, i8imm:$src2),
- "bit.b\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su (load addr:$src1), (i8 imm:$src2))),
- (implicit SRW)]>;
-def BIT16mi : Pseudo<(outs), (ins memsrc:$src1, i16imm:$src2),
- "bit.w\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su (load addr:$src1), (i16 imm:$src2))),
- (implicit SRW)]>;
-
-def BIT8mm : Pseudo<(outs), (ins memsrc:$src1, memsrc:$src2),
- "bit.b\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su (i8 (load addr:$src1)),
- (load addr:$src2))),
- (implicit SRW)]>;
-def BIT16mm : Pseudo<(outs), (ins memsrc:$src1, memsrc:$src2),
- "bit.w\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su (i16 (load addr:$src1)),
- (load addr:$src2))),
+def BIT8ri : I8ri<0x0,
+ (outs), (ins GR8:$src1, i8imm:$src2),
+ "bit.b\t{$src2, $src1}",
+ [(MSP430cmp (and_su GR8:$src1, imm:$src2), 0),
+ (implicit SRW)]>;
+def BIT16ri : I16ri<0x0,
+ (outs), (ins GR16:$src1, i16imm:$src2),
+ "bit.w\t{$src2, $src1}",
+ [(MSP430cmp (and_su GR16:$src1, imm:$src2), 0),
+ (implicit SRW)]>;
+
+def BIT8rm : I8rm<0x0,
+ (outs), (ins GR8:$src1, memdst:$src2),
+ "bit.b\t{$src2, $src1}",
+ [(MSP430cmp (and_su GR8:$src1, (load addr:$src2)), 0),
+ (implicit SRW)]>;
+def BIT16rm : I16rm<0x0,
+ (outs), (ins GR16:$src1, memdst:$src2),
+ "bit.w\t{$src2, $src1}",
+ [(MSP430cmp (and_su GR16:$src1, (load addr:$src2)), 0),
+ (implicit SRW)]>;
+
+def BIT8mr : I8mr<0x0,
+ (outs), (ins memsrc:$src1, GR8:$src2),
+ "bit.b\t{$src2, $src1}",
+ [(MSP430cmp (and_su (load addr:$src1), GR8:$src2), 0),
+ (implicit SRW)]>;
+def BIT16mr : I16mr<0x0,
+ (outs), (ins memsrc:$src1, GR16:$src2),
+ "bit.w\t{$src2, $src1}",
+ [(MSP430cmp (and_su (load addr:$src1), GR16:$src2), 0),
+ (implicit SRW)]>;
+
+def BIT8mi : I8mi<0x0,
+ (outs), (ins memsrc:$src1, i8imm:$src2),
+ "bit.b\t{$src2, $src1}",
+ [(MSP430cmp (and_su (load addr:$src1), (i8 imm:$src2)), 0),
+ (implicit SRW)]>;
+def BIT16mi : I16mi<0x0,
+ (outs), (ins memsrc:$src1, i16imm:$src2),
+ "bit.w\t{$src2, $src1}",
+ [(MSP430cmp (and_su (load addr:$src1), (i16 imm:$src2)), 0),
+ (implicit SRW)]>;
+
+def BIT8mm : I8mm<0x0,
+ (outs), (ins memsrc:$src1, memsrc:$src2),
+ "bit.b\t{$src2, $src1}",
+ [(MSP430cmp (and_su (i8 (load addr:$src1)),
+ (load addr:$src2)),
+ 0),
(implicit SRW)]>;
+def BIT16mm : I16mm<0x0,
+ (outs), (ins memsrc:$src1, memsrc:$src2),
+ "bit.w\t{$src2, $src1}",
+ [(MSP430cmp (and_su (i16 (load addr:$src1)),
+ (load addr:$src2)),
+ 0),
+ (implicit SRW)]>;
} // Defs = [SRW]
//===----------------------------------------------------------------------===//
@@ -923,7 +1116,8 @@ def BIT16mm : Pseudo<(outs), (ins memsrc:$src1, memsrc:$src2),
def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>;
// anyext
-def : Pat<(anyext addr:$src), (MOVZX16rr8 GR8:$src)>;
+def : Pat<(i16 (anyext GR8:$src)),
+ (SUBREG_TO_REG (i16 0), GR8:$src, subreg_8bit)>;
// truncs
def : Pat<(i8 (trunc GR16:$src)),
@@ -996,6 +1190,6 @@ def : Pat<(store (subc (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
// peephole patterns
def : Pat<(and GR16:$src, 255), (ZEXT16r GR16:$src)>;
-def : Pat<(MSP430cmp 0, (trunc (and_su GR16:$src1, GR16:$src2))),
+def : Pat<(MSP430cmp (trunc (and_su GR16:$src1, GR16:$src2)), 0),
(BIT8rr (EXTRACT_SUBREG GR16:$src1, subreg_8bit),
(EXTRACT_SUBREG GR16:$src2, subreg_8bit))>;
diff --git a/lib/Target/MSP430/MSP430TargetMachine.cpp b/lib/Target/MSP430/MSP430TargetMachine.cpp
index 14db406..a0dbac2 100644
--- a/lib/Target/MSP430/MSP430TargetMachine.cpp
+++ b/lib/Target/MSP430/MSP430TargetMachine.cpp
@@ -44,3 +44,9 @@ bool MSP430TargetMachine::addInstSelector(PassManagerBase &PM,
return false;
}
+bool MSP430TargetMachine::addPreEmitPass(PassManagerBase &PM,
+ CodeGenOpt::Level OptLevel) {
+ // Must run branch selection immediately preceding the asm printer.
+ PM.add(createMSP430BranchSelectionPass());
+ return false;
+}
diff --git a/lib/Target/MSP430/MSP430TargetMachine.h b/lib/Target/MSP430/MSP430TargetMachine.h
index d386140..d93ac5c 100644
--- a/lib/Target/MSP430/MSP430TargetMachine.h
+++ b/lib/Target/MSP430/MSP430TargetMachine.h
@@ -55,6 +55,7 @@ public:
}
virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
+ virtual bool addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
}; // MSP430TargetMachine.
} // end namespace llvm
diff --git a/lib/Target/MSP430/Makefile b/lib/Target/MSP430/Makefile
index 4b18bc9..11195a4 100644
--- a/lib/Target/MSP430/Makefile
+++ b/lib/Target/MSP430/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMMSP430CodeGen
TARGET = MSP430
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = MSP430GenRegisterInfo.h.inc MSP430GenRegisterNames.inc \
diff --git a/lib/Target/MSP430/TargetInfo/Makefile b/lib/Target/MSP430/TargetInfo/Makefile
index abb08f2..d17fa7b 100644
--- a/lib/Target/MSP430/TargetInfo/Makefile
+++ b/lib/Target/MSP430/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMMSP430Info
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/Makefile b/lib/Target/Makefile
index 50a360f..281d58b 100644
--- a/lib/Target/Makefile
+++ b/lib/Target/Makefile
@@ -10,6 +10,7 @@
LEVEL = ../..
LIBRARYNAME = LLVMTarget
BUILD_ARCHIVE = 1
+CXXFLAGS = -fno-rtti
# We include this early so we can access the value of TARGETS_TO_BUILD as the
# value for PARALLEL_DIRS which must be set before Makefile.rules is included
diff --git a/lib/Target/Mangler.cpp b/lib/Target/Mangler.cpp
new file mode 100644
index 0000000..ef6defc
--- /dev/null
+++ b/lib/Target/Mangler.cpp
@@ -0,0 +1,179 @@
+//===-- Mangler.cpp - Self-contained c/asm llvm name mangler --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Unified name mangler for assembly backends.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Target/Mangler.h"
+#include "llvm/GlobalValue.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+using namespace llvm;
+
+static bool isAcceptableChar(char C) {
+ if ((C < 'a' || C > 'z') &&
+ (C < 'A' || C > 'Z') &&
+ (C < '0' || C > '9') &&
+ C != '_' && C != '$' && C != '.' && C != '@')
+ return false;
+ return true;
+}
+
+static char HexDigit(int V) {
+ return V < 10 ? V+'0' : V+'A'-10;
+}
+
+static void MangleLetter(SmallVectorImpl<char> &OutName, unsigned char C) {
+ OutName.push_back('_');
+ OutName.push_back(HexDigit(C >> 4));
+ OutName.push_back(HexDigit(C & 15));
+ OutName.push_back('_');
+}
+
+/// NameNeedsEscaping - Return true if the identifier \arg Str needs quotes
+/// for this assembler.
+static bool NameNeedsEscaping(StringRef Str, const MCAsmInfo &MAI) {
+ assert(!Str.empty() && "Cannot create an empty MCSymbol");
+
+ // If the first character is a number and the target does not allow this, we
+ // need quotes.
+ if (!MAI.doesAllowNameToStartWithDigit() && Str[0] >= '0' && Str[0] <= '9')
+ return true;
+
+ // If any of the characters in the string is an unacceptable character, force
+ // quotes.
+ for (unsigned i = 0, e = Str.size(); i != e; ++i)
+ if (!isAcceptableChar(Str[i]))
+ return true;
+ return false;
+}
+
+/// appendMangledName - Add the specified string in mangled form if it uses
+/// any unusual characters.
+static void appendMangledName(SmallVectorImpl<char> &OutName, StringRef Str,
+ const MCAsmInfo *MAI) {
+ // The first character is not allowed to be a number unless the target
+ // explicitly allows it.
+ if ((MAI == 0 || !MAI->doesAllowNameToStartWithDigit()) &&
+ Str[0] >= '0' && Str[0] <= '9') {
+ MangleLetter(OutName, Str[0]);
+ Str = Str.substr(1);
+ }
+
+ for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+ if (!isAcceptableChar(Str[i]))
+ MangleLetter(OutName, Str[i]);
+ else
+ OutName.push_back(Str[i]);
+ }
+}
+
+
+/// appendMangledQuotedName - On systems that support quoted symbols, we still
+/// have to escape some (obscure) characters like " and \n which would break the
+/// assembler's lexing.
+static void appendMangledQuotedName(SmallVectorImpl<char> &OutName,
+ StringRef Str) {
+ for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+ if (Str[i] == '"' || Str[i] == '\n')
+ MangleLetter(OutName, Str[i]);
+ else
+ OutName.push_back(Str[i]);
+ }
+}
+
+
+/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
+/// and the specified name as the global variable name. GVName must not be
+/// empty.
+void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
+ const Twine &GVName, ManglerPrefixTy PrefixTy) {
+ SmallString<256> TmpData;
+ StringRef Name = GVName.toStringRef(TmpData);
+ assert(!Name.empty() && "getNameWithPrefix requires non-empty name");
+
+ // If the global name is not led with \1, add the appropriate prefixes.
+ if (Name[0] == '\1') {
+ Name = Name.substr(1);
+ } else {
+ if (PrefixTy == Mangler::Private) {
+ const char *Prefix = MAI.getPrivateGlobalPrefix();
+ OutName.append(Prefix, Prefix+strlen(Prefix));
+ } else if (PrefixTy == Mangler::LinkerPrivate) {
+ const char *Prefix = MAI.getLinkerPrivateGlobalPrefix();
+ OutName.append(Prefix, Prefix+strlen(Prefix));
+ }
+
+ const char *Prefix = MAI.getGlobalPrefix();
+ if (Prefix[0] == 0)
+ ; // Common noop, no prefix.
+ else if (Prefix[1] == 0)
+ OutName.push_back(Prefix[0]); // Common, one character prefix.
+ else
+ OutName.append(Prefix, Prefix+strlen(Prefix)); // Arbitrary length prefix.
+ }
+
+ // If this is a simple string that doesn't need escaping, just append it.
+ if (!NameNeedsEscaping(Name, MAI) ||
+ // If quotes are supported, they can be used unless the string contains
+ // a quote or newline.
+ (MAI.doesAllowQuotesInName() &&
+ Name.find_first_of("\n\"") == StringRef::npos)) {
+ OutName.append(Name.begin(), Name.end());
+ return;
+ }
+
+ // On systems that do not allow quoted names, we need to mangle most
+ // strange characters.
+ if (!MAI.doesAllowQuotesInName())
+ return appendMangledName(OutName, Name, &MAI);
+
+ // Okay, the system allows quoted strings. We can quote most anything, the
+ // only characters that need escaping are " and \n.
+ assert(Name.find_first_of("\n\"") != StringRef::npos);
+ return appendMangledQuotedName(OutName, Name);
+}
+
+
+/// 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 Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
+ const GlobalValue *GV,
+ bool isImplicitlyPrivate) {
+ ManglerPrefixTy PrefixTy = Mangler::Default;
+ if (GV->hasPrivateLinkage() || isImplicitlyPrivate)
+ PrefixTy = Mangler::Private;
+ else if (GV->hasLinkerPrivateLinkage())
+ PrefixTy = Mangler::LinkerPrivate;
+
+ // If this global has a name, handle it simply.
+ if (GV->hasName())
+ return getNameWithPrefix(OutName, GV->getName(), PrefixTy);
+
+ // Get the ID for the global, assigning a new one if we haven't got one
+ // already.
+ unsigned &ID = AnonGlobalIDs[GV];
+ if (ID == 0) ID = NextAnonGlobalID++;
+
+ // Must mangle the global into a unique ID.
+ getNameWithPrefix(OutName, "__unnamed_" + Twine(ID), PrefixTy);
+}
+
+/// 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.
+std::string Mangler::getNameWithPrefix(const GlobalValue *GV,
+ bool isImplicitlyPrivate) {
+ SmallString<64> Buf;
+ getNameWithPrefix(Buf, GV, isImplicitlyPrivate);
+ return std::string(Buf.begin(), Buf.end());
+}
diff --git a/lib/Target/Mips/AsmPrinter/Makefile b/lib/Target/Mips/AsmPrinter/Makefile
index a2fecf4..aed801e 100644
--- a/lib/Target/Mips/AsmPrinter/Makefile
+++ b/lib/Target/Mips/AsmPrinter/Makefile
@@ -9,6 +9,7 @@
LEVEL = ../../../..
LIBRARYNAME = LLVMMipsAsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' Mips target directory to grab
# private headers
diff --git a/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp b/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
index efd3fb7..9af9bd8 100644
--- a/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
+++ b/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
@@ -37,7 +37,6 @@
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
@@ -45,7 +44,6 @@
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/MathExtras.h"
#include <cctype>
-
using namespace llvm;
STATISTIC(EmittedInsts, "Number of machine instrs printed");
@@ -72,7 +70,6 @@ namespace {
const char *Modifier = 0);
void printFCCOperand(const MachineInstr *MI, int opNum,
const char *Modifier = 0);
- void PrintGlobalVariable(const GlobalVariable *GVar);
void printSavedRegsBitmask(MachineFunction &MF);
void printHex32(unsigned int Value);
@@ -219,15 +216,15 @@ void MipsAsmPrinter::emitFunctionStart(MachineFunction &MF) {
// 2 bits aligned
EmitAlignment(MF.getAlignment(), F);
- O << "\t.globl\t" << CurrentFnName << '\n';
- O << "\t.ent\t" << CurrentFnName << '\n';
+ O << "\t.globl\t" << *CurrentFnSym << '\n';
+ O << "\t.ent\t" << *CurrentFnSym << '\n';
- printVisibility(CurrentFnName, F->getVisibility());
+ printVisibility(CurrentFnSym, F->getVisibility());
if ((MAI->hasDotTypeDotSizeDirective()) && Subtarget->isLinux())
- O << "\t.type\t" << CurrentFnName << ", @function\n";
+ O << "\t.type\t" << *CurrentFnSym << ", @function\n";
- O << CurrentFnName << ":\n";
+ O << *CurrentFnSym << ":\n";
emitFrameDirective(MF);
printSavedRegsBitmask(MF);
@@ -243,9 +240,9 @@ void MipsAsmPrinter::emitFunctionEnd(MachineFunction &MF) {
O << "\t.set\tmacro\n";
O << "\t.set\treorder\n";
- O << "\t.end\t" << CurrentFnName << '\n';
+ O << "\t.end\t" << *CurrentFnSym << '\n';
if (MAI->hasDotTypeDotSizeDirective() && !Subtarget->isLinux())
- O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n';
+ O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
}
/// runOnMachineFunction - This uses the printMachineInstruction()
@@ -346,20 +343,20 @@ void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
break;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_GlobalAddress:
- O << Mang->getMangledName(MO.getGlobal());
+ O << *GetGlobalValueSymbol(MO.getGlobal());
break;
case MachineOperand::MO_ExternalSymbol:
- O << MO.getSymbolName();
+ O << *GetExternalSymbolSymbol(MO.getSymbolName());
break;
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
- << '_' << MO.getIndex();
+ << '_' << MO.getIndex();
break;
case MachineOperand::MO_ConstantPoolIndex:
@@ -425,102 +422,6 @@ void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) {
O << "\t.previous" << '\n';
}
-void MipsAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer())
- return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- O << "\n\n";
- std::string name = Mang->getMangledName(GVar);
- Constant *C = GVar->getInitializer();
- const Type *CTy = C->getType();
- unsigned Size = TD->getTypeAllocSize(CTy);
- const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
- bool printSizeAndType = true;
-
- // A data structure or array is aligned in memory to the largest
- // alignment boundary required by any data type inside it (this matches
- // the Preferred Type Alignment). For integral types, the alignment is
- // the type size.
- unsigned Align;
- if (CTy->getTypeID() == Type::IntegerTyID ||
- CTy->getTypeID() == Type::VoidTyID) {
- assert(!(Size & (Size-1)) && "Alignment is not a power of two!");
- Align = Log2_32(Size);
- } else
- Align = TD->getPreferredTypeAlignmentShift(CTy);
-
- printVisibility(name, GVar->getVisibility());
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- if (C->isNullValue() && !GVar->hasSection()) {
- if (!GVar->isThreadLocal() &&
- (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasLocalLinkage())
- O << "\t.local\t" << name << '\n';
-
- O << MAI->getCOMMDirective() << name << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (1 << Align);
-
- O << '\n';
- return;
- }
- }
- switch (GVar->getLinkage()) {
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::CommonLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- // FIXME: Verify correct for weak.
- // Nonnull linkonce -> weak
- O << "\t.weak " << name << '\n';
- break;
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of their name
- // or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << MAI->getGlobalDirective() << name << '\n';
- // Fall Through
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- case GlobalValue::InternalLinkage:
- if (CVA && CVA->isCString())
- printSizeAndType = false;
- break;
- case GlobalValue::GhostLinkage:
- llvm_unreachable("Should not have any unmaterialized functions!");
- case GlobalValue::DLLImportLinkage:
- llvm_unreachable("DLLImport linkage is not supported by this target!");
- case GlobalValue::DLLExportLinkage:
- llvm_unreachable("DLLExport linkage is not supported by this target!");
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
-
- if (MAI->hasDotTypeDotSizeDirective() && printSizeAndType) {
- O << "\t.type " << name << ",@object\n";
- O << "\t.size " << name << ',' << Size << '\n';
- }
-
- O << name << ":\n";
- EmitGlobalConstant(C);
-}
-
-
// Force static initialization.
extern "C" void LLVMInitializeMipsAsmPrinter() {
RegisterAsmPrinter<MipsAsmPrinter> X(TheMipsTarget);
diff --git a/lib/Target/Mips/Makefile b/lib/Target/Mips/Makefile
index 0780345..4e4d874 100644
--- a/lib/Target/Mips/Makefile
+++ b/lib/Target/Mips/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMMipsCodeGen
TARGET = Mips
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = MipsGenRegisterInfo.h.inc MipsGenRegisterNames.inc \
diff --git a/lib/Target/Mips/MipsCallingConv.td b/lib/Target/Mips/MipsCallingConv.td
index 01fe92e..c2bfb8f 100644
--- a/lib/Target/Mips/MipsCallingConv.td
+++ b/lib/Target/Mips/MipsCallingConv.td
@@ -23,11 +23,11 @@ def RetCC_MipsO32 : CallingConv<[
// i32 are returned in registers V0, V1
CCIfType<[i32], CCAssignToReg<[V0, V1]>>,
- // f32 are returned in registers F0, F1
- CCIfType<[f32], CCAssignToReg<[F0, F1]>>,
+ // f32 are returned in registers F0, F2
+ CCIfType<[f32], CCAssignToReg<[F0, F2]>>,
- // f64 are returned in register D0
- CCIfType<[f64], CCIfSubtarget<"isNotSingleFloat()", CCAssignToReg<[D0]>>>
+ // f64 are returned in register D0, D1
+ CCIfType<[f64], CCIfSubtarget<"isNotSingleFloat()", CCAssignToReg<[D0, D1]>>>
]>;
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp
index a53e918..e3a45d2 100644
--- a/lib/Target/Mips/MipsISelDAGToDAG.cpp
+++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp
@@ -396,9 +396,9 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
else
Op = (Opcode == ISD::UDIVREM ? Mips::DIVu : Mips::DIV);
- SDNode *Node = CurDAG->getMachineNode(Op, dl, MVT::Flag, Op1, Op2);
+ SDNode *MulDiv = CurDAG->getMachineNode(Op, dl, MVT::Flag, Op1, Op2);
- SDValue InFlag = SDValue(Node, 0);
+ SDValue InFlag = SDValue(MulDiv, 0);
SDNode *Lo = CurDAG->getMachineNode(Mips::MFLO, dl, MVT::i32,
MVT::Flag, InFlag);
InFlag = SDValue(Lo,1);
@@ -461,9 +461,18 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
case ISD::ConstantFP: {
ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(Node);
if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) {
- SDValue Zero = CurDAG->getRegister(Mips::ZERO, MVT::i32);
- ReplaceUses(SDValue(Node, 0), Zero);
- return Zero.getNode();
+ SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
+ Mips::ZERO, MVT::i32);
+ SDValue Undef = SDValue(
+ CurDAG->getMachineNode(
+ TargetInstrInfo::IMPLICIT_DEF, dl, MVT::f64), 0);
+ SDNode *MTC = CurDAG->getMachineNode(Mips::MTC1, dl, MVT::f32, Zero);
+ SDValue I0 = CurDAG->getTargetInsertSubreg(Mips::SUBREG_FPEVEN, dl,
+ MVT::f64, Undef, SDValue(MTC, 0));
+ SDValue I1 = CurDAG->getTargetInsertSubreg(Mips::SUBREG_FPODD, dl,
+ MVT::f64, I0, SDValue(MTC, 0));
+ ReplaceUses(SDValue(Node, 0), I1);
+ return I1.getNode();
}
break;
}
@@ -486,10 +495,15 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
/// be loaded with 3 instructions.
case MipsISD::JmpLink: {
if (TM.getRelocationModel() == Reloc::PIC_) {
+ unsigned LastOpNum = Node->getNumOperands()-1;
+
SDValue Chain = Node->getOperand(0);
SDValue Callee = Node->getOperand(1);
- SDValue T9Reg = CurDAG->getRegister(Mips::T9, MVT::i32);
- SDValue InFlag(0, 0);
+ SDValue InFlag;
+
+ // Skip the incomming flag if present
+ if (Node->getOperand(LastOpNum).getValueType() == MVT::Flag)
+ LastOpNum--;
if ( (isa<GlobalAddressSDNode>(Callee)) ||
(isa<ExternalSymbolSDNode>(Callee)) )
@@ -504,18 +518,28 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
Chain = Load.getValue(1);
// Call target must be on T9
- Chain = CurDAG->getCopyToReg(Chain, dl, T9Reg, Load, InFlag);
+ Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Load, InFlag);
} else
/// Indirect call
- Chain = CurDAG->getCopyToReg(Chain, dl, T9Reg, Callee, InFlag);
+ Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Callee, InFlag);
+
+ // Map the JmpLink operands to JALR
+ SDVTList NodeTys = CurDAG->getVTList(MVT::Other, MVT::Flag);
+ SmallVector<SDValue, 8> Ops;
+ Ops.push_back(CurDAG->getRegister(Mips::T9, MVT::i32));
+
+ for (unsigned i = 2, e = LastOpNum+1; i != e; ++i)
+ Ops.push_back(Node->getOperand(i));
+ Ops.push_back(Chain);
+ Ops.push_back(Chain.getValue(1));
// Emit Jump and Link Register
- SDNode *ResNode = CurDAG->getMachineNode(Mips::JALR, dl, MVT::Other,
- MVT::Flag, T9Reg, Chain);
- Chain = SDValue(ResNode, 0);
- InFlag = SDValue(ResNode, 1);
- ReplaceUses(SDValue(Node, 0), Chain);
- ReplaceUses(SDValue(Node, 1), InFlag);
+ SDNode *ResNode = CurDAG->getMachineNode(Mips::JALR, dl, NodeTys,
+ &Ops[0], Ops.size());
+
+ // Replace Chain and InFlag
+ ReplaceUses(SDValue(Node, 0), SDValue(ResNode, 0));
+ ReplaceUses(SDValue(Node, 1), SDValue(ResNode, 1));
return ResNode;
}
}
diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp
index 48b9bdf..1a9bffc 100644
--- a/lib/Target/Mips/MipsInstrInfo.cpp
+++ b/lib/Target/Mips/MipsInstrInfo.cpp
@@ -134,8 +134,6 @@ copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
const TargetRegisterClass *DestRC,
const TargetRegisterClass *SrcRC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
- const MachineFunction *MF = MBB.getParent();
- const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo();
if (I != MBB.end()) DL = I->getDebugLoc();
@@ -156,13 +154,6 @@ copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
else if ((DestRC == Mips::FGR32RegisterClass) &&
(SrcRC == Mips::CPURegsRegisterClass))
BuildMI(MBB, I, DL, get(Mips::MTC1), DestReg).addReg(SrcReg);
- else if ((DestRC == Mips::AFGR64RegisterClass) &&
- (SrcRC == Mips::CPURegsRegisterClass) &&
- (SrcReg == Mips::ZERO)) {
- const unsigned *AliasSet = TRI->getAliasSet(DestReg);
- BuildMI(MBB, I, DL, get(Mips::MTC1), AliasSet[0]).addReg(SrcReg);
- BuildMI(MBB, I, DL, get(Mips::MTC1), AliasSet[1]).addReg(SrcReg);
- }
// Move from/to Hi/Lo registers
else if ((DestRC == Mips::HILORegisterClass) &&
diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td
index 46cf43e..e67bcbf 100644
--- a/lib/Target/Mips/MipsInstrInfo.td
+++ b/lib/Target/Mips/MipsInstrInfo.td
@@ -28,8 +28,8 @@ def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>;
def SDT_MipsCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
// Call
-def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink, [SDNPHasChain,
- SDNPOutFlag]>;
+def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink,
+ [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>;
// Hi and Lo nodes are used to handle global addresses. Used on
// MipsISelLowering to lower stuff like GlobalAddress, ExternalSymbol
@@ -306,7 +306,7 @@ let isCall=1, hasDelaySlot=1,
class JumpLink<bits<6> op, string instr_asm>:
FJ< op,
(outs),
- (ins calltarget:$target),
+ (ins calltarget:$target, variable_ops),
!strconcat(instr_asm, "\t$target"),
[(MipsJmpLink imm:$target)], IIBranch>;
@@ -315,14 +315,14 @@ let isCall=1, hasDelaySlot=1,
FR< op,
func,
(outs),
- (ins CPURegs:$rs),
+ (ins CPURegs:$rs, variable_ops),
!strconcat(instr_asm, "\t$rs"),
[(MipsJmpLink CPURegs:$rs)], IIBranch>;
class BranchLink<string instr_asm>:
FI< 0x1,
(outs),
- (ins CPURegs:$rs, brtarget:$target),
+ (ins CPURegs:$rs, brtarget:$target, variable_ops),
!strconcat(instr_asm, "\t$rs, $target"),
[], IIBranch>;
}
diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp
index cae4181..80fd917 100644
--- a/lib/Target/Mips/MipsRegisterInfo.cpp
+++ b/lib/Target/Mips/MipsRegisterInfo.cpp
@@ -172,7 +172,7 @@ getReservedRegs(const MachineFunction &MF) const
//
// The stack is allocated decrementing the stack pointer on
// the first instruction of a function prologue. Once decremented,
-// all stack referencesare are done thought a positive offset
+// all stack references are done thought a positive offset
// from the stack/frame pointer, so the stack is considering
// to grow up! Otherwise terrible hacks would have to be made
// to get this stack ABI compliant :)
diff --git a/lib/Target/Mips/TargetInfo/Makefile b/lib/Target/Mips/TargetInfo/Makefile
index 32f4e16..f27d49e 100644
--- a/lib/Target/Mips/TargetInfo/Makefile
+++ b/lib/Target/Mips/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMMipsInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/PIC16/AsmPrinter/Makefile b/lib/Target/PIC16/AsmPrinter/Makefile
index f4db57e..27c4045 100644
--- a/lib/Target/PIC16/AsmPrinter/Makefile
+++ b/lib/Target/PIC16/AsmPrinter/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMPIC16AsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' pic16 target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
index 87f5aad..0463596 100644
--- a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
+++ b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
@@ -29,7 +29,6 @@
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include <cstring>
using namespace llvm;
@@ -82,7 +81,7 @@ static int getFunctionColor(const Function *F) {
// Color the Auto section of the given function.
void PIC16AsmPrinter::ColorAutoSection(const Function *F) {
- std::string SectionName = PAN::getAutosSectionName(CurrentFnName);
+ std::string SectionName = PAN::getAutosSectionName(CurrentFnSym->getName());
PIC16Section* Section = PTOF->findPIC16Section(SectionName);
if (Section != NULL) {
int Color = getFunctionColor(F);
@@ -103,11 +102,8 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
// of runOnMachineFunction.
SetupMachineFunction(MF);
- // Get the mangled name.
- const Function *F = MF.getFunction();
- CurrentFnName = Mang->getMangledName(F);
-
// Put the color information from function to its auto section.
+ const Function *F = MF.getFunction();
ColorAutoSection(F);
// Emit the function frame (args and temps).
@@ -117,18 +113,18 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
// Now emit the instructions of function in its code section.
const MCSection *fCodeSection
- = getObjFileLowering().SectionForCode(CurrentFnName);
+ = getObjFileLowering().SectionForCode(CurrentFnSym->getName());
// Start the Code Section.
O << "\n";
OutStreamer.SwitchSection(fCodeSection);
// Emit the frame address of the function at the beginning of code.
- O << "\tretlw low(" << PAN::getFrameLabel(CurrentFnName) << ")\n";
- O << "\tretlw high(" << PAN::getFrameLabel(CurrentFnName) << ")\n";
+ O << "\tretlw low(" << PAN::getFrameLabel(CurrentFnSym->getName()) << ")\n";
+ O << "\tretlw high(" << PAN::getFrameLabel(CurrentFnSym->getName()) << ")\n";
// Emit function start label.
- O << CurrentFnName << ":\n";
+ O << *CurrentFnSym << ":\n";
DebugLoc CurDL;
O << "\n";
@@ -187,24 +183,22 @@ void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
return;
case MachineOperand::MO_GlobalAddress: {
- std::string Sname = Mang->getMangledName(MO.getGlobal());
+ MCSymbol *Sym = GetGlobalValueSymbol(MO.getGlobal());
// FIXME: currently we do not have a memcpy def coming in the module
// by any chance, as we do not link in those as .bc lib. So these calls
// are always external and it is safe to emit an extern.
- if (PAN::isMemIntrinsic(Sname)) {
- LibcallDecls.push_back(createESName(Sname));
- }
+ if (PAN::isMemIntrinsic(Sym->getName()))
+ LibcallDecls.push_back(createESName(Sym->getName()));
- O << Sname;
+ O << *Sym;
break;
}
case MachineOperand::MO_ExternalSymbol: {
const char *Sname = MO.getSymbolName();
// If its a libcall name, record it to decls section.
- if (PAN::getSymbolTag(Sname) == PAN::LIBCALL) {
+ if (PAN::getSymbolTag(Sname) == PAN::LIBCALL)
LibcallDecls.push_back(Sname);
- }
// Record a call to intrinsic to print the extern declaration for it.
std::string Sym = Sname;
@@ -213,11 +207,11 @@ void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
LibcallDecls.push_back(createESName(Sym));
}
- O << Sym;
+ O << Sym;
break;
}
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
default:
@@ -319,16 +313,14 @@ void PIC16AsmPrinter::EmitFunctionDecls(Module &M) {
// Emit declarations for external functions.
O <<"\n"<<MAI->getCommentString() << "Function Declarations - BEGIN." <<"\n";
for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) {
- if (I->isIntrinsic())
- continue;
-
- std::string Name = Mang->getMangledName(I);
- if (Name.compare("@abort") == 0)
+ if (I->isIntrinsic() || I->getName() == "@abort")
continue;
if (!I->isDeclaration() && !I->hasExternalLinkage())
continue;
+ MCSymbol *Sym = GetGlobalValueSymbol(I);
+
// Do not emit memcpy, memset, and memmove here.
// Calls to these routines can be generated in two ways,
// 1. User calling the standard lib function
@@ -337,14 +329,14 @@ void PIC16AsmPrinter::EmitFunctionDecls(Module &M) {
// second case the call is via and externalsym and the prototype is missing.
// So declarations for these are currently always getting printing by
// tracking both kind of references in printInstrunction.
- if (I->isDeclaration() && PAN::isMemIntrinsic(Name)) continue;
+ if (I->isDeclaration() && PAN::isMemIntrinsic(Sym->getName())) continue;
const char *directive = I->isDeclaration() ? MAI->getExternDirective() :
MAI->getGlobalDirective();
- O << directive << Name << "\n";
- O << directive << PAN::getRetvalLabel(Name) << "\n";
- O << directive << PAN::getArgsLabel(Name) << "\n";
+ O << directive << Sym->getName() << "\n";
+ O << directive << PAN::getRetvalLabel(Sym->getName()) << "\n";
+ O << directive << PAN::getArgsLabel(Sym->getName()) << "\n";
}
O << MAI->getCommentString() << "Function Declarations - END." <<"\n";
@@ -356,9 +348,8 @@ void PIC16AsmPrinter::EmitUndefinedVars(Module &M) {
if (!Items.size()) return;
O << "\n" << MAI->getCommentString() << "Imported Variables - BEGIN" << "\n";
- for (unsigned j = 0; j < Items.size(); j++) {
- O << MAI->getExternDirective() << Mang->getMangledName(Items[j]) << "\n";
- }
+ for (unsigned j = 0; j < Items.size(); j++)
+ O << MAI->getExternDirective() << *GetGlobalValueSymbol(Items[j]) << "\n";
O << MAI->getCommentString() << "Imported Variables - END" << "\n";
}
@@ -368,9 +359,8 @@ void PIC16AsmPrinter::EmitDefinedVars(Module &M) {
if (!Items.size()) return;
O << "\n" << MAI->getCommentString() << "Exported Variables - BEGIN" << "\n";
- for (unsigned j = 0; j < Items.size(); j++) {
- O << MAI->getGlobalDirective() << Mang->getMangledName(Items[j]) << "\n";
- }
+ for (unsigned j = 0; j < Items.size(); j++)
+ O << MAI->getGlobalDirective() << *GetGlobalValueSymbol(Items[j]) << "\n";
O << MAI->getCommentString() << "Exported Variables - END" << "\n";
}
@@ -394,19 +384,19 @@ bool PIC16AsmPrinter::doFinalization(Module &M) {
void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
const Function *F = MF.getFunction();
- std::string FuncName = Mang->getMangledName(F);
const TargetData *TD = TM.getTargetData();
// Emit the data section name.
O << "\n";
- PIC16Section *fPDataSection = const_cast<PIC16Section *>(getObjFileLowering().
- SectionForFrame(CurrentFnName));
+ PIC16Section *fPDataSection =
+ const_cast<PIC16Section *>(getObjFileLowering().
+ SectionForFrame(CurrentFnSym->getName()));
fPDataSection->setColor(getFunctionColor(F));
OutStreamer.SwitchSection(fPDataSection);
// Emit function frame label
- O << PAN::getFrameLabel(CurrentFnName) << ":\n";
+ O << PAN::getFrameLabel(CurrentFnSym->getName()) << ":\n";
const Type *RetType = F->getReturnType();
unsigned RetSize = 0;
@@ -418,9 +408,10 @@ void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
// we will need to avoid printing a global directive for Retval label
// in emitExternandGloblas.
if(RetSize > 0)
- O << PAN::getRetvalLabel(CurrentFnName) << " RES " << RetSize << "\n";
+ O << PAN::getRetvalLabel(CurrentFnSym->getName())
+ << " RES " << RetSize << "\n";
else
- O << PAN::getRetvalLabel(CurrentFnName) << ": \n";
+ O << PAN::getRetvalLabel(CurrentFnSym->getName()) << ": \n";
// Emit variable to hold the space for function arguments
unsigned ArgSize = 0;
@@ -430,12 +421,13 @@ void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
ArgSize += TD->getTypeAllocSize(Ty);
}
- O << PAN::getArgsLabel(CurrentFnName) << " RES " << ArgSize << "\n";
+ O << PAN::getArgsLabel(CurrentFnSym->getName()) << " RES " << ArgSize << "\n";
// Emit temporary space
int TempSize = PTLI->GetTmpSize();
if (TempSize > 0)
- O << PAN::getTempdataLabel(CurrentFnName) << " RES " << TempSize << '\n';
+ O << PAN::getTempdataLabel(CurrentFnSym->getName()) << " RES "
+ << TempSize << '\n';
}
@@ -445,10 +437,9 @@ void PIC16AsmPrinter::EmitInitializedDataSection(const PIC16Section *S) {
std::vector<const GlobalVariable*> Items = S->Items;
for (unsigned j = 0; j < Items.size(); j++) {
- std::string Name = Mang->getMangledName(Items[j]);
Constant *C = Items[j]->getInitializer();
int AddrSpace = Items[j]->getType()->getAddressSpace();
- O << Name;
+ O << *GetGlobalValueSymbol(Items[j]);
EmitGlobalConstant(C, AddrSpace);
}
}
@@ -464,11 +455,10 @@ EmitUninitializedDataSection(const PIC16Section *S) {
OutStreamer.SwitchSection(S);
std::vector<const GlobalVariable*> Items = S->Items;
for (unsigned j = 0; j < Items.size(); j++) {
- std::string Name = Mang->getMangledName(Items[j]);
Constant *C = Items[j]->getInitializer();
const Type *Ty = C->getType();
unsigned Size = TD->getTypeAllocSize(Ty);
- O << Name << " RES " << Size << "\n";
+ O << *GetGlobalValueSymbol(Items[j]) << " RES " << Size << "\n";
}
}
diff --git a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
index 838c970..74ab72c 100644
--- a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
+++ b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
@@ -69,9 +69,9 @@ namespace llvm {
bool doInitialization(Module &M);
bool doFinalization(Module &M);
- /// PrintGlobalVariable - Emit the specified global variable and its
+ /// EmitGlobalVariable - Emit the specified global variable and its
/// initializer to the output stream.
- virtual void PrintGlobalVariable(const GlobalVariable *GV) {
+ virtual void EmitGlobalVariable(const GlobalVariable *GV) {
// PIC16 doesn't use normal hooks for this.
}
diff --git a/lib/Target/PIC16/Makefile b/lib/Target/PIC16/Makefile
index 4382eba7..a1dbde5 100644
--- a/lib/Target/PIC16/Makefile
+++ b/lib/Target/PIC16/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMPIC16CodeGen
TARGET = PIC16
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = PIC16GenRegisterInfo.h.inc PIC16GenRegisterNames.inc \
diff --git a/lib/Target/PIC16/PIC16DebugInfo.cpp b/lib/Target/PIC16/PIC16DebugInfo.cpp
index 6e0e3ce..8368a3c 100644
--- a/lib/Target/PIC16/PIC16DebugInfo.cpp
+++ b/lib/Target/PIC16/PIC16DebugInfo.cpp
@@ -259,8 +259,9 @@ void PIC16DbgInfo::ChangeDebugLoc(const MachineFunction &MF,
if (! EmitDebugDirectives) return;
assert (! DL.isUnknown() && "can't change to invalid debug loc");
- MDNode *CU = MF.getDebugLocTuple(DL).Scope;
- unsigned line = MF.getDebugLocTuple(DL).Line;
+ DILocation Loc = MF.getDILocation(DL);
+ MDNode *CU = Loc.getScope().getNode();
+ unsigned line = Loc.getLineNumber();
SwitchToCU(CU);
SwitchToLine(line, IsInBeginFunction);
diff --git a/lib/Target/PIC16/PIC16Passes/Makefile b/lib/Target/PIC16/PIC16Passes/Makefile
index 9684b8d..fb45d71 100644
--- a/lib/Target/PIC16/PIC16Passes/Makefile
+++ b/lib/Target/PIC16/PIC16Passes/Makefile
@@ -10,6 +10,7 @@ LEVEL = ../../../..
TARGET = PIC16
LIBRARYNAME = LLVMpic16passes
BUILD_ARCHIVE = 1
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/PIC16/TargetInfo/Makefile b/lib/Target/PIC16/TargetInfo/Makefile
index 76609f6..9004be8 100644
--- a/lib/Target/PIC16/TargetInfo/Makefile
+++ b/lib/Target/PIC16/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMPIC16Info
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/PowerPC/AsmPrinter/Makefile b/lib/Target/PowerPC/AsmPrinter/Makefile
index 269ef92..4378151 100644
--- a/lib/Target/PowerPC/AsmPrinter/Makefile
+++ b/lib/Target/PowerPC/AsmPrinter/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMPowerPCAsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' PowerPC target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
index d505d38..b89c2b4 100644
--- a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
+++ b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
@@ -27,21 +27,21 @@
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/DwarfWriter.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -58,48 +58,7 @@ STATISTIC(EmittedInsts, "Number of machine instrs printed");
namespace {
class PPCAsmPrinter : public AsmPrinter {
protected:
- struct FnStubInfo {
- MCSymbol *Stub, *LazyPtr, *AnonSymbol;
-
- FnStubInfo() {
- Stub = LazyPtr = AnonSymbol = 0;
- }
-
- void Init(const GlobalValue *GV, Mangler *Mang, MCContext &Ctx) {
- // Already initialized.
- if (Stub != 0) return;
-
- // Get the names.
- SmallString<128> TmpStr;
- Mang->getNameWithPrefix(TmpStr, GV, true);
- MakeSymbols(TmpStr, Ctx);
- }
-
- void Init(StringRef GVName, Mangler *Mang, MCContext &Ctx) {
- assert(!GVName.empty() && "external symbol name shouldn't be empty");
- if (Stub != 0) return; // Already initialized.
- // Get the names for the external symbol name.
- SmallString<128> TmpStr;
- Mang->getNameWithPrefix(TmpStr, GVName, Mangler::Private);
- MakeSymbols(TmpStr, Ctx);
- }
-
- void MakeSymbols(SmallString<128> &TmpStr, MCContext &Ctx) {
- TmpStr += "$stub";
- Stub = Ctx.GetOrCreateSymbol(TmpStr.str());
- TmpStr.erase(TmpStr.end()-5, TmpStr.end()); // Remove $stub
-
- TmpStr += "$lazy_ptr";
- LazyPtr = Ctx.GetOrCreateSymbol(TmpStr.str());
- TmpStr.erase(TmpStr.end()-9, TmpStr.end()); // Remove $lazy_ptr
-
- TmpStr += "$stub$tmp";
- AnonSymbol = Ctx.GetOrCreateSymbol(TmpStr.str());
- }
- };
-
- StringMap<FnStubInfo> FnStubs;
- StringMap<std::string> GVStubs, HiddenGVStubs, TOC;
+ DenseMap<const MCSymbol*, const MCSymbol*> TOC;
const PPCSubtarget &Subtarget;
uint64_t LabelID;
public:
@@ -240,18 +199,26 @@ namespace {
GlobalValue *GV = MO.getGlobal();
if (GV->isDeclaration() || GV->isWeakForLinker()) {
// Dynamically-resolved functions need a stub for the function.
- FnStubInfo &FnInfo = FnStubs[Mang->getMangledName(GV)];
- FnInfo.Init(GV, Mang, OutContext);
- FnInfo.Stub->print(O, MAI);
+ MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$stub");
+ const MCSymbol *&StubSym =
+ MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
+ if (StubSym == 0)
+ StubSym = GetGlobalValueSymbol(GV);
+ O << *Sym;
return;
}
}
if (MO.getType() == MachineOperand::MO_ExternalSymbol) {
- SmallString<128> MangledName;
- Mang->getNameWithPrefix(MangledName, MO.getSymbolName());
- FnStubInfo &FnInfo = FnStubs[MangledName.str()];
- FnInfo.Init(MO.getSymbolName(), Mang, OutContext);
- FnInfo.Stub->print(O, MAI);
+ SmallString<128> TempNameStr;
+ TempNameStr += StringRef(MO.getSymbolName());
+ TempNameStr += StringRef("$stub");
+
+ const MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str());
+ const MCSymbol *&StubSym =
+ MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
+ if (StubSym == 0)
+ StubSym = GetExternalSymbolSymbol(MO.getSymbolName());
+ O << *Sym;
return;
}
}
@@ -338,21 +305,16 @@ namespace {
assert(MO.getType() == MachineOperand::MO_GlobalAddress);
- GlobalValue *GV = MO.getGlobal();
-
- std::string Name = Mang->getMangledName(GV);
+ const MCSymbol *Sym = GetGlobalValueSymbol(MO.getGlobal());
// Map symbol -> label of TOC entry.
- if (TOC.count(Name) == 0) {
- std::string Label;
- Label += MAI->getPrivateGlobalPrefix();
- Label += "C";
- Label += utostr(LabelID++);
+ const MCSymbol *&TOCEntry = TOC[Sym];
+ if (TOCEntry == 0)
+ TOCEntry = OutContext.
+ GetOrCreateSymbol(StringRef(MAI->getPrivateGlobalPrefix()) + "C" +
+ Twine(LabelID++));
- TOC[Name] = Label;
- }
-
- O << TOC[Name] << "@toc";
+ O << *TOCEntry << "@toc";
}
void printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
@@ -381,8 +343,6 @@ namespace {
AU.addRequired<DwarfWriter>();
PPCAsmPrinter::getAnalysisUsage(AU);
}
-
- void PrintGlobalVariable(const GlobalVariable *GVar);
};
/// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
@@ -402,14 +362,14 @@ namespace {
bool doFinalization(Module &M);
void EmitStartOfAsmFile(Module &M);
+ void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs);
+
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<MachineModuleInfo>();
AU.addRequired<DwarfWriter>();
PPCAsmPrinter::getAnalysisUsage(AU);
}
-
- void PrintGlobalVariable(const GlobalVariable *GVar);
};
} // end of anonymous namespace
@@ -422,7 +382,7 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
llvm_unreachable("printOp() does not handle immediate values");
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
@@ -434,42 +394,57 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
<< '_' << MO.getIndex();
return;
case MachineOperand::MO_BlockAddress:
- GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);
+ O << *GetBlockAddressSymbol(MO.getBlockAddress());
return;
case MachineOperand::MO_ExternalSymbol: {
// Computing the address of an external symbol, not calling it.
- std::string Name(MAI->getGlobalPrefix());
- Name += MO.getSymbolName();
-
- if (TM.getRelocationModel() != Reloc::Static) {
- GVStubs[Name] = Name+"$non_lazy_ptr";
- Name += "$non_lazy_ptr";
+ if (TM.getRelocationModel() == Reloc::Static) {
+ O << *GetExternalSymbolSymbol(MO.getSymbolName());
+ return;
}
- O << Name;
+
+ const MCSymbol *NLPSym =
+ OutContext.GetOrCreateSymbol(StringRef(MAI->getGlobalPrefix())+
+ MO.getSymbolName()+"$non_lazy_ptr");
+ const MCSymbol *&StubSym =
+ MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(NLPSym);
+ if (StubSym == 0)
+ StubSym = GetExternalSymbolSymbol(MO.getSymbolName());
+
+ O << *NLPSym;
return;
}
case MachineOperand::MO_GlobalAddress: {
// Computing the address of a global symbol, not calling it.
GlobalValue *GV = MO.getGlobal();
- std::string Name;
+ MCSymbol *SymToPrint;
// External or weakly linked global variables need non-lazily-resolved stubs
if (TM.getRelocationModel() != Reloc::Static &&
(GV->isDeclaration() || GV->isWeakForLinker())) {
if (!GV->hasHiddenVisibility()) {
- Name = Mang->getMangledName(GV, "$non_lazy_ptr", true);
- GVStubs[Mang->getMangledName(GV)] = Name;
+ SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
+ const MCSymbol *&StubSym =
+ MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(SymToPrint);
+ if (StubSym == 0)
+ StubSym = GetGlobalValueSymbol(GV);
} else if (GV->isDeclaration() || GV->hasCommonLinkage() ||
GV->hasAvailableExternallyLinkage()) {
- Name = Mang->getMangledName(GV, "$non_lazy_ptr", true);
- HiddenGVStubs[Mang->getMangledName(GV)] = Name;
+ SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
+
+ const MCSymbol *&StubSym =
+ MMI->getObjFileInfo<MachineModuleInfoMachO>().
+ getHiddenGVStubEntry(SymToPrint);
+ if (StubSym == 0)
+ StubSym = GetGlobalValueSymbol(GV);
} else {
- Name = Mang->getMangledName(GV);
+ SymToPrint = GetGlobalValueSymbol(GV);
}
} else {
- Name = Mang->getMangledName(GV);
+ SymToPrint = GetGlobalValueSymbol(GV);
}
- O << Name;
+
+ O << *SymToPrint;
printOffset(MO.getOffset());
return;
@@ -641,34 +616,34 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
case Function::InternalLinkage: // Symbols default to internal.
break;
case Function::ExternalLinkage:
- O << "\t.global\t" << CurrentFnName << '\n'
- << "\t.type\t" << CurrentFnName << ", @function\n";
+ O << "\t.global\t" << *CurrentFnSym << '\n' << "\t.type\t";
+ O << *CurrentFnSym << ", @function\n";
break;
case Function::LinkerPrivateLinkage:
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
case Function::LinkOnceAnyLinkage:
case Function::LinkOnceODRLinkage:
- O << "\t.global\t" << CurrentFnName << '\n';
- O << "\t.weak\t" << CurrentFnName << '\n';
+ O << "\t.global\t" << *CurrentFnSym << '\n';
+ O << "\t.weak\t" << *CurrentFnSym << '\n';
break;
}
- printVisibility(CurrentFnName, F->getVisibility());
+ printVisibility(CurrentFnSym, F->getVisibility());
EmitAlignment(MF.getAlignment(), F);
if (Subtarget.isPPC64()) {
// Emit an official procedure descriptor.
- // FIXME 64-bit SVR4: Use MCSection here?
+ // FIXME 64-bit SVR4: Use MCSection here!
O << "\t.section\t\".opd\",\"aw\"\n";
O << "\t.align 3\n";
- O << CurrentFnName << ":\n";
- O << "\t.quad .L." << CurrentFnName << ",.TOC.@tocbase\n";
+ O << *CurrentFnSym << ":\n";
+ O << "\t.quad .L." << *CurrentFnSym << ",.TOC.@tocbase\n";
O << "\t.previous\n";
- O << ".L." << CurrentFnName << ":\n";
+ O << ".L." << *CurrentFnSym << ":\n";
} else {
- O << CurrentFnName << ":\n";
+ O << *CurrentFnSym << ":\n";
}
// Emit pre-function debug information.
@@ -688,7 +663,7 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
}
- O << "\t.size\t" << CurrentFnName << ",.-" << CurrentFnName << '\n';
+ O << "\t.size\t" << *CurrentFnSym << ",.-" << *CurrentFnSym << '\n';
OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
@@ -702,92 +677,6 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
return false;
}
-void PPCLinuxAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer())
- return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- std::string name = Mang->getMangledName(GVar);
-
- printVisibility(name, GVar->getVisibility());
-
- Constant *C = GVar->getInitializer();
- const Type *Type = C->getType();
- unsigned Size = TD->getTypeAllocSize(Type);
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- if (C->isNullValue() && /* FIXME: Verify correct */
- !GVar->hasSection() &&
- (GVar->hasLocalLinkage() || GVar->hasExternalLinkage() ||
- GVar->isWeakForLinker())) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasExternalLinkage()) {
- O << "\t.global " << name << '\n';
- O << "\t.type " << name << ", @object\n";
- O << name << ":\n";
- O << "\t.zero " << Size << '\n';
- } else if (GVar->hasLocalLinkage()) {
- O << MAI->getLCOMMDirective() << name << ',' << Size;
- } else {
- O << ".comm " << name << ',' << Size;
- }
- if (VerboseAsm) {
- O << "\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'";
- }
- O << '\n';
- return;
- }
-
- switch (GVar->getLinkage()) {
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- O << "\t.global " << name << '\n'
- << "\t.type " << name << ", @object\n"
- << "\t.weak " << name << '\n';
- break;
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << "\t.global " << name << '\n'
- << "\t.type " << name << ", @object\n";
- // FALL THROUGH
- case GlobalValue::InternalLinkage:
- case GlobalValue::PrivateLinkage:
- break;
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
- O << name << ":";
- if (VerboseAsm) {
- O << "\t\t\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'";
- }
- O << '\n';
-
- EmitGlobalConstant(C);
- O << '\n';
-}
-
bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
const TargetData *TD = TM.getTargetData();
@@ -797,10 +686,11 @@ bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
// FIXME 64-bit SVR4: Use MCSection here?
O << "\t.section\t\".toc\",\"aw\"\n";
- for (StringMap<std::string>::iterator I = TOC.begin(), E = TOC.end();
- I != E; ++I) {
- O << I->second << ":\n";
- O << "\t.tc " << I->getKeyData() << "[TC]," << I->getKeyData() << '\n';
+ // FIXME: This is nondeterminstic!
+ for (DenseMap<const MCSymbol*, const MCSymbol*>::iterator I = TOC.begin(),
+ E = TOC.end(); I != E; ++I) {
+ O << *I->second << ":\n";
+ O << "\t.tc " << *I->first << "[TC]," << *I->first << '\n';
}
}
@@ -829,22 +719,22 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
case Function::InternalLinkage: // Symbols default to internal.
break;
case Function::ExternalLinkage:
- O << "\t.globl\t" << CurrentFnName << '\n';
+ O << "\t.globl\t" << *CurrentFnSym << '\n';
break;
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
case Function::LinkOnceAnyLinkage:
case Function::LinkOnceODRLinkage:
case Function::LinkerPrivateLinkage:
- O << "\t.globl\t" << CurrentFnName << '\n';
- O << "\t.weak_definition\t" << CurrentFnName << '\n';
+ O << "\t.globl\t" << *CurrentFnSym << '\n';
+ O << "\t.weak_definition\t" << *CurrentFnSym << '\n';
break;
}
- printVisibility(CurrentFnName, F->getVisibility());
+ printVisibility(CurrentFnSym, F->getVisibility());
EmitAlignment(MF.getAlignment(), F);
- O << CurrentFnName << ":\n";
+ O << *CurrentFnSym << ":\n";
// Emit pre-function debug information.
DW->BeginFunction(&MF);
@@ -926,203 +816,110 @@ void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
}
-void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer())
- return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar)) {
- if (TM.getRelocationModel() == Reloc::Static) {
- if (GVar->getName() == "llvm.global_ctors")
- O << ".reference .constructors_used\n";
- else if (GVar->getName() == "llvm.global_dtors")
- O << ".reference .destructors_used\n";
- }
- return;
- }
-
- std::string name = Mang->getMangledName(GVar);
- printVisibility(name, GVar->getVisibility());
-
- Constant *C = GVar->getInitializer();
- const Type *Type = C->getType();
- unsigned Size = TD->getTypeAllocSize(Type);
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
-
- const MCSection *TheSection =
- getObjFileLowering().SectionForGlobal(GVar, Mang, TM);
- OutStreamer.SwitchSection(TheSection);
-
- /// FIXME: Drive this off the section!
- if (C->isNullValue() && /* FIXME: Verify correct */
- !GVar->hasSection() &&
- (GVar->hasLocalLinkage() || GVar->hasExternalLinkage() ||
- GVar->isWeakForLinker()) &&
- // Don't put things that should go in the cstring section into "comm".
- !TheSection->getKind().isMergeableCString()) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasExternalLinkage()) {
- O << "\t.globl " << name << '\n';
- O << "\t.zerofill __DATA, __common, " << name << ", "
- << Size << ", " << Align;
- } else if (GVar->hasLocalLinkage()) {
- O << MAI->getLCOMMDirective() << name << ',' << Size << ',' << Align;
- } else if (!GVar->hasCommonLinkage()) {
- O << "\t.globl " << name << '\n'
- << MAI->getWeakDefDirective() << name << '\n';
- EmitAlignment(Align, GVar);
- O << name << ":";
- if (VerboseAsm) {
- O << "\t\t\t\t" << MAI->getCommentString() << " ";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- EmitGlobalConstant(C);
- return;
- } else {
- O << ".comm " << name << ',' << Size;
- // Darwin 9 and above support aligned common data.
- if (Subtarget.isDarwin9())
- O << ',' << Align;
- }
- if (VerboseAsm) {
- O << "\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'";
- }
- O << '\n';
- return;
- }
-
- switch (GVar->getLinkage()) {
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- O << "\t.globl " << name << '\n'
- << "\t.weak_definition " << name << '\n';
- break;
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << "\t.globl " << name << '\n';
- // FALL THROUGH
- case GlobalValue::InternalLinkage:
- case GlobalValue::PrivateLinkage:
- break;
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
- O << name << ":";
- if (VerboseAsm) {
- O << "\t\t\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'";
- }
- O << '\n';
-
- EmitGlobalConstant(C);
- O << '\n';
+static const MCSymbol *GetLazyPtr(const MCSymbol *Sym, MCContext &Ctx) {
+ // Remove $stub suffix, add $lazy_ptr.
+ SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end()-5);
+ TmpStr += "$lazy_ptr";
+ return Ctx.GetOrCreateSymbol(TmpStr.str());
}
-bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
- const TargetData *TD = TM.getTargetData();
-
- bool isPPC64 = TD->getPointerSizeInBits() == 64;
+static const MCSymbol *GetAnonSym(const MCSymbol *Sym, MCContext &Ctx) {
+ // Add $tmp suffix to $stub, yielding $stub$tmp.
+ SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end());
+ TmpStr += "$tmp";
+ return Ctx.GetOrCreateSymbol(TmpStr.str());
+}
- // Darwin/PPC always uses mach-o.
+void PPCDarwinAsmPrinter::
+EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
+ bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64;
+
TargetLoweringObjectFileMachO &TLOFMacho =
static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
-
- const MCSection *LSPSection = 0;
- if (!FnStubs.empty()) // .lazy_symbol_pointer
- LSPSection = TLOFMacho.getLazySymbolPointerSection();
-
+ // .lazy_symbol_pointer
+ const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
// Output stubs for dynamically-linked functions
- if (TM.getRelocationModel() == Reloc::PIC_ && !FnStubs.empty()) {
+ if (TM.getRelocationModel() == Reloc::PIC_) {
const MCSection *StubSection =
- TLOFMacho.getMachOSection("__TEXT", "__picsymbolstub1",
- MCSectionMachO::S_SYMBOL_STUBS |
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
- 32, SectionKind::getText());
- for (StringMap<FnStubInfo>::iterator I = FnStubs.begin(), E = FnStubs.end();
- I != E; ++I) {
+ TLOFMacho.getMachOSection("__TEXT", "__picsymbolstub1",
+ MCSectionMachO::S_SYMBOL_STUBS |
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+ 32, SectionKind::getText());
+ for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
OutStreamer.SwitchSection(StubSection);
EmitAlignment(4);
- const FnStubInfo &Info = I->second;
- Info.Stub->print(O, MAI);
- O << ":\n";
- O << "\t.indirect_symbol " << I->getKeyData() << '\n';
+
+ const MCSymbol *Stub = Stubs[i].first;
+ const MCSymbol *RawSym = Stubs[i].second;
+ const MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
+ const MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
+
+ O << *Stub << ":\n";
+ O << "\t.indirect_symbol " << *RawSym << '\n';
O << "\tmflr r0\n";
- O << "\tbcl 20,31,";
- Info.AnonSymbol->print(O, MAI);
- O << '\n';
- Info.AnonSymbol->print(O, MAI);
- O << ":\n";
+ O << "\tbcl 20,31," << *AnonSymbol << '\n';
+ O << *AnonSymbol << ":\n";
O << "\tmflr r11\n";
- O << "\taddis r11,r11,ha16(";
- Info.LazyPtr->print(O, MAI);
- O << '-';
- Info.AnonSymbol->print(O, MAI);
- O << ")\n";
+ O << "\taddis r11,r11,ha16(" << *LazyPtr << '-' << *AnonSymbol
+ << ")\n";
O << "\tmtlr r0\n";
- O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16(";
- Info.LazyPtr->print(O, MAI);
- O << '-';
- Info.AnonSymbol->print(O, MAI);
- O << ")(r11)\n";
+ O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16(" << *LazyPtr
+ << '-' << *AnonSymbol << ")(r11)\n";
O << "\tmtctr r12\n";
O << "\tbctr\n";
OutStreamer.SwitchSection(LSPSection);
- Info.LazyPtr->print(O, MAI);
- O << ":\n";
- O << "\t.indirect_symbol " << I->getKeyData() << '\n';
- O << (isPPC64 ? "\t.quad" : "\t.long") << " dyld_stub_binding_helper\n";
- }
- } else if (!FnStubs.empty()) {
- const MCSection *StubSection =
- TLOFMacho.getMachOSection("__TEXT","__symbol_stub1",
- MCSectionMachO::S_SYMBOL_STUBS |
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
- 16, SectionKind::getText());
-
- for (StringMap<FnStubInfo>::iterator I = FnStubs.begin(), E = FnStubs.end();
- I != E; ++I) {
- OutStreamer.SwitchSection(StubSection);
- EmitAlignment(4);
- const FnStubInfo &Info = I->second;
- Info.Stub->print(O, MAI);
- O << ":\n";
- O << "\t.indirect_symbol " << I->getKeyData() << '\n';
- O << "\tlis r11,ha16(";
- Info.LazyPtr->print(O, MAI);
- O << ")\n";
- O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16(";
- Info.LazyPtr->print(O, MAI);
- O << ")(r11)\n";
- O << "\tmtctr r12\n";
- O << "\tbctr\n";
- OutStreamer.SwitchSection(LSPSection);
- Info.LazyPtr->print(O, MAI);
- O << ":\n";
- O << "\t.indirect_symbol " << I->getKeyData() << '\n';
+ O << *LazyPtr << ":\n";
+ O << "\t.indirect_symbol " << *RawSym << '\n';
O << (isPPC64 ? "\t.quad" : "\t.long") << " dyld_stub_binding_helper\n";
}
+ O << '\n';
+ return;
}
-
+
+ const MCSection *StubSection =
+ TLOFMacho.getMachOSection("__TEXT","__symbol_stub1",
+ MCSectionMachO::S_SYMBOL_STUBS |
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+ 16, SectionKind::getText());
+ for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
+ const MCSymbol *Stub = Stubs[i].first;
+ const MCSymbol *RawSym = Stubs[i].second;
+ const MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
+
+ OutStreamer.SwitchSection(StubSection);
+ EmitAlignment(4);
+ O << *Stub << ":\n";
+ O << "\t.indirect_symbol " << *RawSym << '\n';
+ O << "\tlis r11,ha16(" << *LazyPtr << ")\n";
+ O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16(" << *LazyPtr
+ << ")(r11)\n";
+ O << "\tmtctr r12\n";
+ O << "\tbctr\n";
+ OutStreamer.SwitchSection(LSPSection);
+ O << *LazyPtr << ":\n";
+ O << "\t.indirect_symbol " << *RawSym << '\n';
+ O << (isPPC64 ? "\t.quad" : "\t.long") << " dyld_stub_binding_helper\n";
+ }
+
O << '\n';
+}
+
+
+bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
+ bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64;
+
+ // Darwin/PPC always uses mach-o.
+ TargetLoweringObjectFileMachO &TLOFMacho =
+ static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
+ MachineModuleInfoMachO &MMIMacho =
+ MMI->getObjFileInfo<MachineModuleInfoMachO>();
+
+ MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList();
+ if (!Stubs.empty())
+ EmitFunctionStubs(Stubs);
if (MAI->doesSupportExceptionHandling() && MMI) {
// Add the (possibly multiple) personalities to the set of global values.
@@ -1130,33 +927,39 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
const std::vector<Function *> &Personalities = MMI->getPersonalities();
for (std::vector<Function *>::const_iterator I = Personalities.begin(),
E = Personalities.end(); I != E; ++I) {
- if (*I)
- GVStubs[Mang->getMangledName(*I)] =
- Mang->getMangledName(*I, "$non_lazy_ptr", true);
+ if (*I) {
+ const MCSymbol *NLPSym =
+ GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
+ const MCSymbol *&StubSym = MMIMacho.getGVStubEntry(NLPSym);
+ StubSym = GetGlobalValueSymbol(*I);
+ }
}
}
+ // Output stubs for dynamically-linked functions.
+ Stubs = MMIMacho.GetGVStubList();
+
// Output macho stubs for external and common global variables.
- if (!GVStubs.empty()) {
+ if (!Stubs.empty()) {
// Switch with ".non_lazy_symbol_pointer" directive.
OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
EmitAlignment(isPPC64 ? 3 : 2);
- for (StringMap<std::string>::iterator I = GVStubs.begin(),
- E = GVStubs.end(); I != E; ++I) {
- O << I->second << ":\n";
- O << "\t.indirect_symbol " << I->getKeyData() << '\n';
+ for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
+ O << *Stubs[i].first << ":\n";
+ O << "\t.indirect_symbol " << *Stubs[i].second << '\n';
O << (isPPC64 ? "\t.quad\t0\n" : "\t.long\t0\n");
}
}
- if (!HiddenGVStubs.empty()) {
+ Stubs = MMIMacho.GetHiddenGVStubList();
+ if (!Stubs.empty()) {
OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
EmitAlignment(isPPC64 ? 3 : 2);
- for (StringMap<std::string>::iterator I = HiddenGVStubs.begin(),
- E = HiddenGVStubs.end(); I != E; ++I) {
- O << I->second << ":\n";
- O << (isPPC64 ? "\t.quad\t" : "\t.long\t") << I->getKeyData() << '\n';
+
+ for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
+ O << *Stubs[i].first << ":\n";
+ O << (isPPC64 ? "\t.quad\t" : "\t.long\t") << *Stubs[i].second << '\n';
}
}
@@ -1165,7 +968,7 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
// implementation of multiple entry points). If this doesn't occur, the
// linker can safely perform dead code stripping. Since LLVM never generates
// code that does this, it is always safe to set.
- OutStreamer.EmitAssemblerFlag(MCStreamer::SubsectionsViaSymbols);
+ OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
return AsmPrinter::doFinalization(M);
}
diff --git a/lib/Target/PowerPC/Makefile b/lib/Target/PowerPC/Makefile
index 4015d4a..cd30011 100644
--- a/lib/Target/PowerPC/Makefile
+++ b/lib/Target/PowerPC/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMPowerPCCodeGen
TARGET = PPC
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = PPCGenInstrNames.inc PPCGenRegisterNames.inc \
diff --git a/lib/Target/PowerPC/PPCMCAsmInfo.cpp b/lib/Target/PowerPC/PPCMCAsmInfo.cpp
index ee6deb5..d2ff3b7 100644
--- a/lib/Target/PowerPC/PPCMCAsmInfo.cpp
+++ b/lib/Target/PowerPC/PPCMCAsmInfo.cpp
@@ -29,7 +29,6 @@ PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) {
CommentString = "#";
GlobalPrefix = "";
PrivateGlobalPrefix = ".L";
- UsedDirective = "\t# .no_dead_strip\t";
WeakRefDirective = "\t.weak\t";
// Uses '.section' before '.bss' directive
@@ -53,7 +52,7 @@ PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) {
SetDirective = "\t.set";
Data64bitsDirective = is64Bit ? "\t.quad\t" : 0;
AlignmentIsInBytes = false;
- LCOMMDirective = "\t.lcomm\t";
+ HasLCOMMDirective = true;
AssemblerDialect = 0; // Old-Style mnemonics.
}
diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp
index 8079c6e..c7f7882 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.cpp
+++ b/lib/Target/PowerPC/PPCTargetMachine.cpp
@@ -194,4 +194,31 @@ bool PPCTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
return false;
}
-
+/// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are 4-byte,
+/// 8-byte, and target default. The CIE is hard-coded to indicate that the LSDA
+/// pointer in the FDE section is an "sdata4", and should be encoded as a 4-byte
+/// pointer by default. However, some systems may require a different size due
+/// to bugs or other conditions. We will default to a 4-byte encoding unless the
+/// system tells us otherwise.
+///
+/// The issue is when the CIE says their is an LSDA. That mandates that every
+/// FDE have an LSDA slot. But if the function does not need an LSDA. There
+/// needs to be some way to signify there is none. The LSDA is encoded as
+/// pc-rel. But you don't look for some magic value after adding the pc. You
+/// have to look for a zero before adding the pc. The problem is that the size
+/// of the zero to look for depends on the encoding. The unwinder bug in SL is
+/// that it always checks for a pointer-size zero. So on x86_64 it looks for 8
+/// bytes of zero. If you have an LSDA, it works fine since the 8-bytes are
+/// non-zero so it goes ahead and then reads the value based on the encoding.
+/// But if you use sdata4 and there is no LSDA, then the test for zero gives a
+/// false negative and the unwinder thinks there is an LSDA.
+///
+/// FIXME: This call-back isn't good! We should be using the correct encoding
+/// regardless of the system. However, there are some systems which have bugs
+/// that prevent this from occuring.
+DwarfLSDAEncoding::Encoding PPCTargetMachine::getLSDAEncoding() const {
+ if (Subtarget.isDarwin() && Subtarget.getDarwinVers() != 10)
+ return DwarfLSDAEncoding::Default;
+
+ return DwarfLSDAEncoding::EightByte;
+}
diff --git a/lib/Target/PowerPC/PPCTargetMachine.h b/lib/Target/PowerPC/PPCTargetMachine.h
index 3399ac8..4afcb23 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.h
+++ b/lib/Target/PowerPC/PPCTargetMachine.h
@@ -62,6 +62,18 @@ public:
return &MachOWriterInfo;
}
+ /// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are
+ /// 4-byte, 8-byte, and target default. The CIE is hard-coded to indicate that
+ /// the LSDA pointer in the FDE section is an "sdata4", and should be encoded
+ /// as a 4-byte pointer by default. However, some systems may require a
+ /// different size due to bugs or other conditions. We will default to a
+ /// 4-byte encoding unless the system tells us otherwise.
+ ///
+ /// FIXME: This call-back isn't good! We should be using the correct encoding
+ /// regardless of the system. However, there are some systems which have bugs
+ /// that prevent this from occuring.
+ virtual DwarfLSDAEncoding::Encoding getLSDAEncoding() const;
+
// Pass Pipeline Configuration
virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
virtual bool addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
diff --git a/lib/Target/PowerPC/TargetInfo/Makefile b/lib/Target/PowerPC/TargetInfo/Makefile
index a101aa4..16d0167 100644
--- a/lib/Target/PowerPC/TargetInfo/Makefile
+++ b/lib/Target/PowerPC/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMPowerPCInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/README.txt b/lib/Target/README.txt
index 69da35f..080ea42 100644
--- a/lib/Target/README.txt
+++ b/lib/Target/README.txt
@@ -1665,3 +1665,54 @@ int foo() {
//===---------------------------------------------------------------------===//
+Missed instcombine transformation:
+define i1 @a(i32 %x) nounwind readnone {
+entry:
+ %cmp = icmp eq i32 %x, 30
+ %sub = add i32 %x, -30
+ %cmp2 = icmp ugt i32 %sub, 9
+ %or = or i1 %cmp, %cmp2
+ ret i1 %or
+}
+This should be optimized to a single compare. Testcase derived from gcc.
+
+//===---------------------------------------------------------------------===//
+
+Missed instcombine transformation:
+void b();
+void a(int x) { if (((1<<x)&8)==0) b(); }
+
+The shift should be optimized out. Testcase derived from gcc.
+
+//===---------------------------------------------------------------------===//
+
+Missed instcombine or reassociate transformation:
+int a(int a, int b) { return (a==12)&(b>47)&(b<58); }
+
+The sgt and slt should be combined into a single comparison. Testcase derived
+from gcc.
+
+//===---------------------------------------------------------------------===//
+
+Missed instcombine transformation:
+define i32 @a(i32 %x) nounwind readnone {
+entry:
+ %shr = lshr i32 %x, 5 ; <i32> [#uses=1]
+ %xor = xor i32 %shr, 67108864 ; <i32> [#uses=1]
+ %sub = add i32 %xor, -67108864 ; <i32> [#uses=1]
+ ret i32 %sub
+}
+
+This function is equivalent to "ashr i32 %x, 5". Testcase derived from gcc.
+
+//===---------------------------------------------------------------------===//
+
+isSafeToLoadUnconditionally should allow a GEP of a global/alloca with constant
+indicies within the bounds of the allocated object. Reduced example:
+
+const int a[] = {3,6};
+int b(int y) { int* x = y ? &a[0] : &a[1]; return *x; }
+
+All the loads should be eliminated. Testcase derived from gcc.
+
+//===---------------------------------------------------------------------===//
diff --git a/lib/Target/Sparc/AsmPrinter/Makefile b/lib/Target/Sparc/AsmPrinter/Makefile
index a856828..404fad1 100644
--- a/lib/Target/Sparc/AsmPrinter/Makefile
+++ b/lib/Target/Sparc/AsmPrinter/Makefile
@@ -8,6 +8,8 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMSparcAsmPrinter
+CXXFLAGS = -fno-rtti
+
# Hack: we need to include 'main' Sparc target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
index cd85dd4..8fc4e5a 100644
--- a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
+++ b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
@@ -34,7 +34,6 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include <cctype>
#include <cstring>
@@ -61,7 +60,6 @@ namespace {
return "Sparc Assembly Printer";
}
- void PrintGlobalVariable(const GlobalVariable *GVar);
void printOperand(const MachineInstr *MI, int opNum);
void printMemOperand(const MachineInstr *MI, int opNum,
const char *Modifier = 0);
@@ -138,7 +136,7 @@ bool SparcAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
DW->EndFunction(&MF);
// We didn't modify anything.
- O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n';
+ O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
return false;
}
@@ -156,7 +154,7 @@ void SparcAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
case Function::DLLExportLinkage:
case Function::ExternalLinkage:
// Function is externally visible
- O << "\t.global\t" << CurrentFnName << '\n';
+ O << "\t.global\t" << *CurrentFnSym << '\n';
break;
case Function::LinkerPrivateLinkage:
case Function::LinkOnceAnyLinkage:
@@ -164,14 +162,14 @@ void SparcAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
// Function is weak
- O << "\t.weak\t" << CurrentFnName << '\n' ;
+ O << "\t.weak\t" << *CurrentFnSym << '\n';
break;
}
- printVisibility(CurrentFnName, F->getVisibility());
+ printVisibility(CurrentFnSym, F->getVisibility());
- O << "\t.type\t" << CurrentFnName << ", #function\n";
- O << CurrentFnName << ":\n";
+ O << "\t.type\t" << *CurrentFnSym << ", #function\n";
+ O << *CurrentFnSym << ":\n";
}
@@ -195,10 +193,10 @@ void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
O << (int)MO.getImm();
break;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_GlobalAddress:
- O << Mang->getMangledName(MO.getGlobal());
+ O << *GetGlobalValueSymbol(MO.getGlobal());
break;
case MachineOperand::MO_ExternalSymbol:
O << MO.getSymbolName();
@@ -277,85 +275,6 @@ void SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
O << SPARCCondCodeToString((SPCC::CondCodes)CC);
}
-void SparcAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer())
- return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- O << "\n\n";
- std::string name = Mang->getMangledName(GVar);
- Constant *C = GVar->getInitializer();
- unsigned Size = TD->getTypeAllocSize(C->getType());
- unsigned Align = TD->getPreferredAlignment(GVar);
-
- printVisibility(name, GVar->getVisibility());
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- if (C->isNullValue() && !GVar->hasSection()) {
- if (!GVar->isThreadLocal() &&
- (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasLocalLinkage())
- O << "\t.local " << name << '\n';
-
- O << MAI->getCOMMDirective() << name << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (1 << Align);
-
- O << '\n';
- return;
- }
- }
-
- switch (GVar->getLinkage()) {
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage: // FIXME: Verify correct for weak.
- case GlobalValue::WeakODRLinkage: // FIXME: Verify correct for weak.
- // Nonnull linkonce -> weak
- O << "\t.weak " << name << '\n';
- break;
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << MAI->getGlobalDirective() << name << '\n';
- // FALL THROUGH
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- case GlobalValue::GhostLinkage:
- llvm_unreachable("Should not have any unmaterialized functions!");
- case GlobalValue::DLLImportLinkage:
- llvm_unreachable("DLLImport linkage is not supported by this target!");
- case GlobalValue::DLLExportLinkage:
- llvm_unreachable("DLLExport linkage is not supported by this target!");
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
-
- if (MAI->hasDotTypeDotSizeDirective()) {
- O << "\t.type " << name << ",#object\n";
- O << "\t.size " << name << ',' << Size << '\n';
- }
-
- O << name << ":\n";
- EmitGlobalConstant(C);
-}
-
/// PrintAsmOperand - Print out an operand for an inline asm expression.
///
bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
diff --git a/lib/Target/Sparc/Makefile b/lib/Target/Sparc/Makefile
index 6714b4d..d3e2a89 100644
--- a/lib/Target/Sparc/Makefile
+++ b/lib/Target/Sparc/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMSparcCodeGen
TARGET = Sparc
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = SparcGenRegisterInfo.h.inc SparcGenRegisterNames.inc \
diff --git a/lib/Target/Sparc/TargetInfo/Makefile b/lib/Target/Sparc/TargetInfo/Makefile
index 641ed87..0827fdb 100644
--- a/lib/Target/Sparc/TargetInfo/Makefile
+++ b/lib/Target/Sparc/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMSparcInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/SystemZ/AsmPrinter/Makefile b/lib/Target/SystemZ/AsmPrinter/Makefile
index 9a350df..36cd6f8 100644
--- a/lib/Target/SystemZ/AsmPrinter/Makefile
+++ b/lib/Target/SystemZ/AsmPrinter/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMSystemZAsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' SystemZ target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
index e97e7ca..5c3fe37 100644
--- a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
+++ b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
@@ -35,8 +35,6 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
-
using namespace llvm;
STATISTIC(EmittedInsts, "Number of machine instrs printed");
@@ -73,7 +71,6 @@ namespace {
void emitFunctionHeader(const MachineFunction &MF);
bool runOnMachineFunction(MachineFunction &F);
- void PrintGlobalVariable(const GlobalVariable* GVar);
void getAnalysisUsage(AnalysisUsage &AU) const {
AsmPrinter::getAnalysisUsage(AU);
@@ -99,20 +96,20 @@ void SystemZAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
case Function::LinkerPrivateLinkage:
break;
case Function::ExternalLinkage:
- O << "\t.globl\t" << CurrentFnName << '\n';
+ O << "\t.globl\t" << *CurrentFnSym << '\n';
break;
case Function::LinkOnceAnyLinkage:
case Function::LinkOnceODRLinkage:
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
- O << "\t.weak\t" << CurrentFnName << '\n';
+ O << "\t.weak\t" << *CurrentFnSym << '\n';
break;
}
- printVisibility(CurrentFnName, F->getVisibility());
+ printVisibility(CurrentFnSym, F->getVisibility());
- O << "\t.type\t" << CurrentFnName << ",@function\n"
- << CurrentFnName << ":\n";
+ O << "\t.type\t" << *CurrentFnSym << ",@function\n";
+ O << *CurrentFnSym << ":\n";
}
bool SystemZAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
@@ -138,7 +135,7 @@ bool SystemZAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n';
+ O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
// Print out jump tables referenced by the function.
EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
@@ -169,13 +166,11 @@ void SystemZAsmPrinter::printPCRelImmOperand(const MachineInstr *MI, int OpNum){
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_GlobalAddress: {
const GlobalValue *GV = MO.getGlobal();
- std::string Name = Mang->getMangledName(GV);
-
- O << Name;
+ O << *GetGlobalValueSymbol(GV);
// Assemble calls via PLT for externally visible symbols if PIC.
if (TM.getRelocationModel() == Reloc::PIC_ &&
@@ -226,7 +221,7 @@ void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
@@ -239,17 +234,11 @@ void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
printOffset(MO.getOffset());
break;
- case MachineOperand::MO_GlobalAddress: {
- const GlobalValue *GV = MO.getGlobal();
- std::string Name = Mang->getMangledName(GV);
-
- O << Name;
+ case MachineOperand::MO_GlobalAddress:
+ O << *GetGlobalValueSymbol(MO.getGlobal());
break;
- }
case MachineOperand::MO_ExternalSymbol: {
- std::string Name(MAI->getGlobalPrefix());
- Name += MO.getSymbolName();
- O << Name;
+ O << *GetExternalSymbolSymbol(MO.getSymbolName());
break;
}
default:
@@ -304,87 +293,6 @@ void SystemZAsmPrinter::printRRIAddrOperand(const MachineInstr *MI, int OpNum,
assert(!Index.getReg() && "Should allocate base register first!");
}
-void SystemZAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer())
- return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- std::string name = Mang->getMangledName(GVar);
- Constant *C = GVar->getInitializer();
- unsigned Size = TD->getTypeAllocSize(C->getType());
- unsigned Align = std::max(1U, TD->getPreferredAlignmentLog(GVar));
-
- printVisibility(name, GVar->getVisibility());
-
- O << "\t.type\t" << name << ",@object\n";
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- if (C->isNullValue() && !GVar->hasSection() &&
- !GVar->isThreadLocal() &&
- (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
-
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasLocalLinkage())
- O << "\t.local\t" << name << '\n';
-
- O << MAI->getCOMMDirective() << name << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
-
- if (VerboseAsm) {
- O << "\t\t" << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- return;
- }
-
- switch (GVar->getLinkage()) {
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- O << "\t.weak\t" << name << '\n';
- break;
- case GlobalValue::DLLExportLinkage:
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << "\t.globl " << name << '\n';
- // FALL THROUGH
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- default:
- assert(0 && "Unknown linkage type!");
- }
-
- // Use 16-bit alignment by default to simplify bunch of stuff
- EmitAlignment(Align, GVar, 1);
- O << name << ":";
- if (VerboseAsm) {
- O << "\t\t\t\t" << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << name << ", " << Size << '\n';
-
- EmitGlobalConstant(C);
-}
-
// Force static initialization.
extern "C" void LLVMInitializeSystemZAsmPrinter() {
RegisterAsmPrinter<SystemZAsmPrinter> X(TheSystemZTarget);
diff --git a/lib/Target/SystemZ/Makefile b/lib/Target/SystemZ/Makefile
index f1097eb..6d0cbbd 100644
--- a/lib/Target/SystemZ/Makefile
+++ b/lib/Target/SystemZ/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMSystemZCodeGen
TARGET = SystemZ
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = SystemZGenRegisterInfo.h.inc SystemZGenRegisterNames.inc \
diff --git a/lib/Target/SystemZ/SystemZMCAsmInfo.cpp b/lib/Target/SystemZ/SystemZMCAsmInfo.cpp
index 8ea11c9..ba392bb 100644
--- a/lib/Target/SystemZ/SystemZMCAsmInfo.cpp
+++ b/lib/Target/SystemZ/SystemZMCAsmInfo.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "SystemZMCAsmInfo.h"
+#include "llvm/MC/MCSectionELF.h"
using namespace llvm;
SystemZMCAsmInfo::SystemZMCAsmInfo(const Target &T, const StringRef &TT) {
@@ -21,6 +22,9 @@ SystemZMCAsmInfo::SystemZMCAsmInfo(const Target &T, const StringRef &TT) {
WeakRefDirective = "\t.weak\t";
SetDirective = "\t.set\t";
PCSymbol = ".";
+}
- NonexecutableStackDirective = "\t.section\t.note.GNU-stack,\"\",@progbits";
+MCSection *SystemZMCAsmInfo::getNonexecutableStackSection(MCContext &Ctx) const{
+ return MCSectionELF::Create(".note.GNU-stack", MCSectionELF::SHT_PROGBITS,
+ 0, SectionKind::getMetadata(), false, Ctx);
}
diff --git a/lib/Target/SystemZ/SystemZMCAsmInfo.h b/lib/Target/SystemZ/SystemZMCAsmInfo.h
index 3bebcb7..00cb99b 100644
--- a/lib/Target/SystemZ/SystemZMCAsmInfo.h
+++ b/lib/Target/SystemZ/SystemZMCAsmInfo.h
@@ -22,8 +22,9 @@ namespace llvm {
struct SystemZMCAsmInfo : public MCAsmInfo {
explicit SystemZMCAsmInfo(const Target &T, const StringRef &TT);
+ virtual MCSection *getNonexecutableStackSection(MCContext &Ctx) const;
};
-
+
} // namespace llvm
#endif
diff --git a/lib/Target/SystemZ/TargetInfo/Makefile b/lib/Target/SystemZ/TargetInfo/Makefile
index 0be80eb..9f36b2c 100644
--- a/lib/Target/SystemZ/TargetInfo/Makefile
+++ b/lib/Target/SystemZ/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMSystemZInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/MC/MCAsmParser.cpp b/lib/Target/TargetAsmLexer.cpp
index 2287e89..0ae6c14 100644
--- a/lib/MC/MCAsmParser.cpp
+++ b/lib/Target/TargetAsmLexer.cpp
@@ -1,4 +1,4 @@
-//===-- MCAsmParser.cpp - Abstract Asm Parser Interface -------------------===//
+//===-- llvm/Target/TargetAsmLexer.cpp - Target Assembly Lexer ------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,12 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCAsmParser.h"
-
+#include "llvm/Target/TargetAsmLexer.h"
using namespace llvm;
-MCAsmParser::MCAsmParser() {
-}
-
-MCAsmParser::~MCAsmParser() {
-}
+TargetAsmLexer::TargetAsmLexer(const Target &T) : TheTarget(T) {}
+TargetAsmLexer::~TargetAsmLexer() {}
diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp
index 70e8008..a231ebc 100644
--- a/lib/Target/TargetLoweringObjectFile.cpp
+++ b/lib/Target/TargetLoweringObjectFile.cpp
@@ -22,11 +22,11 @@
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
@@ -141,9 +141,18 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV,
return SectionKind::getThreadData();
}
+ // Variables with common linkage always get classified as common.
+ if (GVar->hasCommonLinkage())
+ return SectionKind::getCommon();
+
// Variable can be easily put to BSS section.
- if (isSuitableForBSS(GVar))
+ if (isSuitableForBSS(GVar)) {
+ if (GVar->hasLocalLinkage())
+ return SectionKind::getBSSLocal();
+ else if (GVar->hasExternalLinkage())
+ return SectionKind::getBSSExtern();
return SectionKind::getBSS();
+ }
Constant *C = GVar->getInitializer();
@@ -300,6 +309,7 @@ getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
IsIndirect = false;
IsPCRel = false;
+ // FIXME: Use GetGlobalValueSymbol.
SmallString<128> Name;
Mang->getNameWithPrefix(Name, GV, false);
return MCSymbolRefExpr::Create(Name.str(), getContext());
@@ -464,30 +474,30 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
static SectionKind
-getELFKindForNamedSection(const char *Name, SectionKind K) {
- if (Name[0] != '.') return K;
+getELFKindForNamedSection(StringRef Name, SectionKind K) {
+ if (Name.empty() || Name[0] != '.') return K;
// Some lame default implementation based on some magic section names.
- if (strcmp(Name, ".bss") == 0 ||
- strncmp(Name, ".bss.", 5) == 0 ||
- strncmp(Name, ".gnu.linkonce.b.", 16) == 0 ||
- strncmp(Name, ".llvm.linkonce.b.", 17) == 0 ||
- strcmp(Name, ".sbss") == 0 ||
- strncmp(Name, ".sbss.", 6) == 0 ||
- strncmp(Name, ".gnu.linkonce.sb.", 17) == 0 ||
- strncmp(Name, ".llvm.linkonce.sb.", 18) == 0)
+ if (Name == ".bss" ||
+ Name.startswith(".bss.") ||
+ Name.startswith(".gnu.linkonce.b.") ||
+ Name.startswith(".llvm.linkonce.b.") ||
+ Name == ".sbss" ||
+ Name.startswith(".sbss.") ||
+ Name.startswith(".gnu.linkonce.sb.") ||
+ Name.startswith(".llvm.linkonce.sb."))
return SectionKind::getBSS();
- if (strcmp(Name, ".tdata") == 0 ||
- strncmp(Name, ".tdata.", 7) == 0 ||
- strncmp(Name, ".gnu.linkonce.td.", 17) == 0 ||
- strncmp(Name, ".llvm.linkonce.td.", 18) == 0)
+ if (Name == ".tdata" ||
+ Name.startswith(".tdata.") ||
+ Name.startswith(".gnu.linkonce.td.") ||
+ Name.startswith(".llvm.linkonce.td."))
return SectionKind::getThreadData();
- if (strcmp(Name, ".tbss") == 0 ||
- strncmp(Name, ".tbss.", 6) == 0 ||
- strncmp(Name, ".gnu.linkonce.tb.", 17) == 0 ||
- strncmp(Name, ".llvm.linkonce.tb.", 18) == 0)
+ if (Name == ".tbss" ||
+ Name.startswith(".tbss.") ||
+ Name.startswith(".gnu.linkonce.tb.") ||
+ Name.startswith(".llvm.linkonce.tb."))
return SectionKind::getThreadBSS();
return K;
@@ -543,7 +553,7 @@ getELFSectionFlags(SectionKind K) {
const MCSection *TargetLoweringObjectFileELF::
getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const {
- const char *SectionName = GV->getSection().c_str();
+ StringRef SectionName = GV->getSection();
// Infer section flags from the section name if we can.
Kind = getELFKindForNamedSection(SectionName, Kind);
@@ -560,7 +570,6 @@ static const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) {
if (Kind.isThreadData()) return ".gnu.linkonce.td.";
if (Kind.isThreadBSS()) return ".gnu.linkonce.tb.";
- if (Kind.isBSS()) return ".gnu.linkonce.b.";
if (Kind.isDataNoRel()) return ".gnu.linkonce.d.";
if (Kind.isDataRelLocal()) return ".gnu.linkonce.d.rel.local.";
if (Kind.isDataRel()) return ".gnu.linkonce.d.rel.";
@@ -576,20 +585,13 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
// If this global is linkonce/weak and the target handles this by emitting it
// into a 'uniqued' section name, create and return the section now.
- if (GV->isWeakForLinker()) {
+ if (GV->isWeakForLinker() && !Kind.isCommon() && !Kind.isBSS()) {
const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
- SmallString<128> Name, MangledName;
+ SmallString<128> Name;
Name.append(Prefix, Prefix+strlen(Prefix));
Mang->getNameWithPrefix(Name, GV, false);
-
- raw_svector_ostream OS(MangledName);
- MCSymbol::printMangledName(Name, OS, 0);
- OS.flush();
-
- return getELFSection(MangledName.str(),
- getELFSectionType(MangledName.str(), Kind),
- getELFSectionFlags(Kind),
- Kind);
+ return getELFSection(Name.str(), getELFSectionType(Name.str(), Kind),
+ getELFSectionFlags(Kind), Kind);
}
if (Kind.isText()) return TextSection;
@@ -614,7 +616,7 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
std::string Name = SizeSpec + utostr(Align);
- return getELFSection(Name.c_str(), MCSectionELF::SHT_PROGBITS,
+ return getELFSection(Name, MCSectionELF::SHT_PROGBITS,
MCSectionELF::SHF_ALLOC |
MCSectionELF::SHF_MERGE |
MCSectionELF::SHF_STRINGS,
@@ -636,7 +638,10 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
if (Kind.isThreadData()) return TLSDataSection;
if (Kind.isThreadBSS()) return TLSBSSSection;
- if (Kind.isBSS()) return BSSSection;
+ // Note: we claim that common symbols are put in BSSSection, but they are
+ // really emitted with the magic .comm directive, which creates a symbol table
+ // entry but not a section.
+ if (Kind.isBSS() || Kind.isCommon()) return BSSSection;
if (Kind.isDataNoRel()) return DataSection;
if (Kind.isDataRelLocal()) return DataRelLocalSection;
@@ -762,7 +767,13 @@ void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx,
DataCoalSection
= getMachOSection("__DATA","__datacoal_nt", MCSectionMachO::S_COALESCED,
SectionKind::getDataRel());
-
+ DataCommonSection
+ = getMachOSection("__DATA","__common", MCSectionMachO::S_ZEROFILL,
+ SectionKind::getBSS());
+ DataBSSSection
+ = getMachOSection("__DATA","__bss", MCSectionMachO::S_ZEROFILL,
+ SectionKind::getBSS());
+
LazySymbolPointerSection
= getMachOSection("__DATA", "__la_symbol_ptr",
@@ -921,6 +932,16 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
if (Kind.isReadOnlyWithRel())
return ConstDataSection;
+ // Put zero initialized globals with strong external linkage in the
+ // DATA, __common section with the .zerofill directive.
+ if (Kind.isBSSExtern())
+ return DataCommonSection;
+
+ // Put zero initialized globals with local linkage in __DATA,__bss directive
+ // with the .zerofill directive (aka .lcomm).
+ if (Kind.isBSSLocal())
+ return DataBSSSection;
+
// Otherwise, just drop the variable in the normal data section.
return DataSection;
}
@@ -955,7 +976,8 @@ shouldEmitUsedDirectiveFor(const GlobalValue *GV, Mangler *Mang) const {
// FIXME: ObjC metadata is currently emitted as internal symbols that have
// \1L and \0l prefixes on them. Fix them to be Private/LinkerPrivate and
// this horrible hack can go away.
- const std::string &Name = Mang->getMangledName(GV);
+ SmallString<64> Name;
+ Mang->getNameWithPrefix(Name, GV, false);
if (Name[0] == 'L' || Name[0] == 'l')
return false;
}
@@ -1064,7 +1086,7 @@ void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx,
const MCSection *TargetLoweringObjectFileCOFF::
getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const {
- return getCOFFSection(GV->getSection().c_str(), false, Kind);
+ return getCOFFSection(GV->getSection(), false, Kind);
}
static const char *getCOFFSectionPrefixForUniqueGlobal(SectionKind Kind) {
diff --git a/lib/Target/TargetMachine.cpp b/lib/Target/TargetMachine.cpp
index 46bc9a3..fec59b5 100644
--- a/lib/Target/TargetMachine.cpp
+++ b/lib/Target/TargetMachine.cpp
@@ -46,7 +46,6 @@ namespace llvm {
bool DisableJumpTables;
bool StrongPHIElim;
bool AsmVerbosityDefault(false);
- bool DisableScheduling;
}
static cl::opt<bool, true>
@@ -198,11 +197,6 @@ EnableStrongPHIElim(cl::Hidden, "strong-phi-elim",
cl::desc("Use strong PHI elimination."),
cl::location(StrongPHIElim),
cl::init(false));
-static cl::opt<bool, true>
-DisableInstScheduling("disable-scheduling",
- cl::desc("Disable instruction scheduling"),
- cl::location(DisableScheduling),
- cl::init(false));
//---------------------------------------------------------------------------
// TargetMachine Class
diff --git a/lib/Target/X86/AsmParser/CMakeLists.txt b/lib/Target/X86/AsmParser/CMakeLists.txt
index 034d5ab..40dbdd7 100644
--- a/lib/Target/X86/AsmParser/CMakeLists.txt
+++ b/lib/Target/X86/AsmParser/CMakeLists.txt
@@ -1,6 +1,7 @@
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. )
add_llvm_library(LLVMX86AsmParser
+ X86AsmLexer.cpp
X86AsmParser.cpp
)
add_dependencies(LLVMX86AsmParser X86CodeGenTable_gen)
diff --git a/lib/Target/X86/AsmParser/Makefile b/lib/Target/X86/AsmParser/Makefile
index 25fb0a2..288b985 100644
--- a/lib/Target/X86/AsmParser/Makefile
+++ b/lib/Target/X86/AsmParser/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMX86AsmParser
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' x86 target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/X86/AsmParser/X86AsmLexer.cpp b/lib/Target/X86/AsmParser/X86AsmLexer.cpp
new file mode 100644
index 0000000..1a62044
--- /dev/null
+++ b/lib/Target/X86/AsmParser/X86AsmLexer.cpp
@@ -0,0 +1,43 @@
+//===-- X86AsmLexer.cpp - Tokenize X86 assembly to AsmTokens --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Target/TargetAsmLexer.h"
+#include "llvm/Target/TargetRegistry.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
+#include "X86.h"
+
+using namespace llvm;
+
+namespace {
+
+class X86AsmLexer : public TargetAsmLexer {
+ const MCAsmInfo &AsmInfo;
+protected:
+ AsmToken LexToken();
+public:
+ X86AsmLexer(const Target &T, const MCAsmInfo &MAI)
+ : TargetAsmLexer(T), AsmInfo(MAI) {
+ }
+};
+
+}
+
+AsmToken X86AsmLexer::LexToken() {
+ return AsmToken(AsmToken::Error, "", 0);
+}
+
+extern "C" void LLVMInitializeX86AsmLexer() {
+ RegisterAsmLexer<X86AsmLexer> X(TheX86_32Target);
+ RegisterAsmLexer<X86AsmLexer> Y(TheX86_64Target);
+}
+
+//#define REGISTERS_ONLY
+//#include "../X86GenAsmMatcher.inc"
+//#undef REGISTERS_ONLY
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index c4ae5d2..7a9218e 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -11,12 +11,12 @@
#include "X86.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/MC/MCAsmLexer.h"
-#include "llvm/MC/MCAsmParser.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCParsedAsmOperand.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetAsmParser.h"
@@ -37,11 +37,10 @@ private:
bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
- bool ParseRegister(X86Operand &Op);
+ bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
- bool ParseOperand(X86Operand &Op);
-
- bool ParseMemOperand(X86Operand &Op);
+ X86Operand *ParseOperand();
+ X86Operand *ParseMemOperand();
bool ParseDirectiveWord(unsigned Size, SMLoc L);
@@ -51,10 +50,6 @@ private:
bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCInst &Inst);
- /// MatchRegisterName - Match the given string to a register name, or 0 if
- /// there is no match.
- unsigned MatchRegisterName(const StringRef &Name);
-
/// }
public:
@@ -69,19 +64,27 @@ public:
} // end anonymous namespace
+/// @name Auto-generated Match Functions
+/// {
+
+static unsigned MatchRegisterName(const StringRef &Name);
+
+/// }
namespace {
/// X86Operand - Instances of this class represent a parsed X86 machine
/// instruction.
struct X86Operand : public MCParsedAsmOperand {
- enum {
+ enum KindTy {
Token,
Register,
Immediate,
Memory
} Kind;
+ SMLoc StartLoc, EndLoc;
+
union {
struct {
const char *Data;
@@ -105,6 +108,14 @@ struct X86Operand : public MCParsedAsmOperand {
} Mem;
};
+ X86Operand(KindTy K, SMLoc Start, SMLoc End)
+ : Kind(K), StartLoc(Start), EndLoc(End) {}
+
+ /// getStartLoc - Get the location of the first token of this operand.
+ SMLoc getStartLoc() const { return StartLoc; }
+ /// getEndLoc - Get the location of the last token of this operand.
+ SMLoc getEndLoc() const { return EndLoc; }
+
StringRef getToken() const {
assert(Kind == Token && "Invalid access!");
return StringRef(Tok.Data, Tok.Length);
@@ -192,44 +203,40 @@ struct X86Operand : public MCParsedAsmOperand {
Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
}
- static X86Operand CreateToken(StringRef Str) {
- X86Operand Res;
- Res.Kind = Token;
- Res.Tok.Data = Str.data();
- Res.Tok.Length = Str.size();
+ static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
+ X86Operand *Res = new X86Operand(Token, Loc, Loc);
+ Res->Tok.Data = Str.data();
+ Res->Tok.Length = Str.size();
return Res;
}
- static X86Operand CreateReg(unsigned RegNo) {
- X86Operand Res;
- Res.Kind = Register;
- Res.Reg.RegNo = RegNo;
+ static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc) {
+ X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
+ Res->Reg.RegNo = RegNo;
return Res;
}
- static X86Operand CreateImm(const MCExpr *Val) {
- X86Operand Res;
- Res.Kind = Immediate;
- Res.Imm.Val = Val;
+ static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){
+ X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
+ Res->Imm.Val = Val;
return Res;
}
- static X86Operand CreateMem(unsigned SegReg, const MCExpr *Disp,
- unsigned BaseReg, unsigned IndexReg,
- unsigned Scale) {
+ static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
+ unsigned BaseReg, unsigned IndexReg,
+ unsigned Scale, SMLoc StartLoc, SMLoc EndLoc) {
// We should never just have a displacement, that would be an immediate.
assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
// The scale should always be one of {1,2,4,8}.
assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
"Invalid scale!");
- X86Operand Res;
- Res.Kind = Memory;
- Res.Mem.SegReg = SegReg;
- Res.Mem.Disp = Disp;
- Res.Mem.BaseReg = BaseReg;
- Res.Mem.IndexReg = IndexReg;
- Res.Mem.Scale = Scale;
+ X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
+ Res->Mem.SegReg = SegReg;
+ Res->Mem.Disp = Disp;
+ Res->Mem.BaseReg = BaseReg;
+ Res->Mem.IndexReg = IndexReg;
+ Res->Mem.Scale = Scale;
return Res;
}
};
@@ -237,52 +244,57 @@ struct X86Operand : public MCParsedAsmOperand {
} // end anonymous namespace.
-bool X86ATTAsmParser::ParseRegister(X86Operand &Op) {
- const AsmToken &TokPercent = getLexer().getTok();
- (void)TokPercent; // Avoid warning when assertions are disabled.
+bool X86ATTAsmParser::ParseRegister(unsigned &RegNo,
+ SMLoc &StartLoc, SMLoc &EndLoc) {
+ RegNo = 0;
+ const AsmToken &TokPercent = Parser.getTok();
assert(TokPercent.is(AsmToken::Percent) && "Invalid token kind!");
- getLexer().Lex(); // Eat percent token.
+ StartLoc = TokPercent.getLoc();
+ Parser.Lex(); // Eat percent token.
- const AsmToken &Tok = getLexer().getTok();
+ const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Identifier))
return Error(Tok.getLoc(), "invalid register name");
// FIXME: Validate register for the current architecture; we have to do
// validation later, so maybe there is no need for this here.
- unsigned RegNo;
-
RegNo = MatchRegisterName(Tok.getString());
if (RegNo == 0)
return Error(Tok.getLoc(), "invalid register name");
- Op = X86Operand::CreateReg(RegNo);
- getLexer().Lex(); // Eat identifier token.
-
+ EndLoc = Tok.getLoc();
+ Parser.Lex(); // Eat identifier token.
return false;
}
-bool X86ATTAsmParser::ParseOperand(X86Operand &Op) {
+X86Operand *X86ATTAsmParser::ParseOperand() {
switch (getLexer().getKind()) {
default:
- return ParseMemOperand(Op);
- case AsmToken::Percent:
+ return ParseMemOperand();
+ case AsmToken::Percent: {
// FIXME: if a segment register, this could either be just the seg reg, or
// the start of a memory operand.
- return ParseRegister(Op);
+ unsigned RegNo;
+ SMLoc Start, End;
+ if (ParseRegister(RegNo, Start, End)) return 0;
+ return X86Operand::CreateReg(RegNo, Start, End);
+ }
case AsmToken::Dollar: {
// $42 -> immediate.
- getLexer().Lex();
+ SMLoc Start = Parser.getTok().getLoc(), End;
+ Parser.Lex();
const MCExpr *Val;
- if (getParser().ParseExpression(Val))
- return true;
- Op = X86Operand::CreateImm(Val);
- return false;
+ if (getParser().ParseExpression(Val, End))
+ return 0;
+ return X86Operand::CreateImm(Val, Start, End);
}
}
}
/// ParseMemOperand: segment: disp(basereg, indexreg, scale)
-bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
+X86Operand *X86ATTAsmParser::ParseMemOperand() {
+ SMLoc MemStart = Parser.getTok().getLoc();
+
// FIXME: If SegReg ':' (e.g. %gs:), eat and remember.
unsigned SegReg = 0;
@@ -292,47 +304,47 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
// it.
const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
if (getLexer().isNot(AsmToken::LParen)) {
- if (getParser().ParseExpression(Disp)) return true;
+ SMLoc ExprEnd;
+ if (getParser().ParseExpression(Disp, ExprEnd)) return 0;
// After parsing the base expression we could either have a parenthesized
// memory address or not. If not, return now. If so, eat the (.
if (getLexer().isNot(AsmToken::LParen)) {
// Unless we have a segment register, treat this as an immediate.
- if (SegReg)
- Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
- else
- Op = X86Operand::CreateImm(Disp);
- return false;
+ if (SegReg == 0)
+ return X86Operand::CreateImm(Disp, MemStart, ExprEnd);
+ return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
}
// Eat the '('.
- getLexer().Lex();
+ Parser.Lex();
} else {
// Okay, we have a '('. We don't know if this is an expression or not, but
// so we have to eat the ( to see beyond it.
- getLexer().Lex(); // Eat the '('.
+ SMLoc LParenLoc = Parser.getTok().getLoc();
+ Parser.Lex(); // Eat the '('.
if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
// Nothing to do here, fall into the code below with the '(' part of the
// memory operand consumed.
} else {
+ SMLoc ExprEnd;
+
// It must be an parenthesized expression, parse it now.
- if (getParser().ParseParenExpression(Disp))
- return true;
+ if (getParser().ParseParenExpression(Disp, ExprEnd))
+ return 0;
// After parsing the base expression we could either have a parenthesized
// memory address or not. If not, return now. If so, eat the (.
if (getLexer().isNot(AsmToken::LParen)) {
// Unless we have a segment register, treat this as an immediate.
- if (SegReg)
- Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
- else
- Op = X86Operand::CreateImm(Disp);
- return false;
+ if (SegReg == 0)
+ return X86Operand::CreateImm(Disp, LParenLoc, ExprEnd);
+ return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
}
// Eat the '('.
- getLexer().Lex();
+ Parser.Lex();
}
}
@@ -341,13 +353,12 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
if (getLexer().is(AsmToken::Percent)) {
- if (ParseRegister(Op))
- return true;
- BaseReg = Op.getReg();
+ SMLoc L;
+ if (ParseRegister(BaseReg, L, L)) return 0;
}
if (getLexer().is(AsmToken::Comma)) {
- getLexer().Lex(); // Eat the comma.
+ Parser.Lex(); // Eat the comma.
// Following the comma we should have either an index register, or a scale
// value. We don't support the later form, but we want to parse it
@@ -356,82 +367,89 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
// Not that even though it would be completely consistent to support syntax
// like "1(%eax,,1)", the assembler doesn't.
if (getLexer().is(AsmToken::Percent)) {
- if (ParseRegister(Op))
- return true;
- IndexReg = Op.getReg();
+ SMLoc L;
+ if (ParseRegister(IndexReg, L, L)) return 0;
if (getLexer().isNot(AsmToken::RParen)) {
// Parse the scale amount:
// ::= ',' [scale-expression]
- if (getLexer().isNot(AsmToken::Comma))
- return true;
- getLexer().Lex(); // Eat the comma.
+ if (getLexer().isNot(AsmToken::Comma)) {
+ Error(Parser.getTok().getLoc(),
+ "expected comma in scale expression");
+ return 0;
+ }
+ Parser.Lex(); // Eat the comma.
if (getLexer().isNot(AsmToken::RParen)) {
- SMLoc Loc = getLexer().getTok().getLoc();
+ SMLoc Loc = Parser.getTok().getLoc();
int64_t ScaleVal;
if (getParser().ParseAbsoluteExpression(ScaleVal))
- return true;
+ return 0;
// Validate the scale amount.
- if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8)
- return Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
+ if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
+ Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
+ return 0;
+ }
Scale = (unsigned)ScaleVal;
}
}
} else if (getLexer().isNot(AsmToken::RParen)) {
// Otherwise we have the unsupported form of a scale amount without an
// index.
- SMLoc Loc = getLexer().getTok().getLoc();
+ SMLoc Loc = Parser.getTok().getLoc();
int64_t Value;
if (getParser().ParseAbsoluteExpression(Value))
- return true;
+ return 0;
- return Error(Loc, "cannot have scale factor without index register");
+ Error(Loc, "cannot have scale factor without index register");
+ return 0;
}
}
// Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
- if (getLexer().isNot(AsmToken::RParen))
- return Error(getLexer().getTok().getLoc(),
- "unexpected token in memory operand");
- getLexer().Lex(); // Eat the ')'.
+ if (getLexer().isNot(AsmToken::RParen)) {
+ Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
+ return 0;
+ }
+ SMLoc MemEnd = Parser.getTok().getLoc();
+ Parser.Lex(); // Eat the ')'.
- Op = X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale);
- return false;
+ return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
+ MemStart, MemEnd);
}
bool X86ATTAsmParser::
ParseInstruction(const StringRef &Name, SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
- Operands.push_back(new X86Operand(X86Operand::CreateToken(Name)));
+ Operands.push_back(X86Operand::CreateToken(Name, NameLoc));
- SMLoc Loc = getLexer().getTok().getLoc();
if (getLexer().isNot(AsmToken::EndOfStatement)) {
// Parse '*' modifier.
if (getLexer().is(AsmToken::Star)) {
- getLexer().Lex(); // Eat the star.
- Operands.push_back(new X86Operand(X86Operand::CreateToken("*")));
+ SMLoc Loc = Parser.getTok().getLoc();
+ Operands.push_back(X86Operand::CreateToken("*", Loc));
+ Parser.Lex(); // Eat the star.
}
// Read the first operand.
- X86Operand Op;
- if (ParseOperand(Op))
+ if (X86Operand *Op = ParseOperand())
+ Operands.push_back(Op);
+ else
return true;
-
- Operands.push_back(new X86Operand(Op));
-
+
while (getLexer().is(AsmToken::Comma)) {
- getLexer().Lex(); // Eat the comma.
+ Parser.Lex(); // Eat the comma.
// Parse and remember the operand.
- if (ParseOperand(Op))
+ if (X86Operand *Op = ParseOperand())
+ Operands.push_back(Op);
+ else
return true;
- Operands.push_back(new X86Operand(Op));
}
}
@@ -454,7 +472,7 @@ bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
if (getParser().ParseExpression(Value))
return true;
- getParser().getStreamer().EmitValue(Value, Size);
+ getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/);
if (getLexer().is(AsmToken::EndOfStatement))
break;
@@ -462,18 +480,21 @@ bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
// FIXME: Improve diagnostic.
if (getLexer().isNot(AsmToken::Comma))
return Error(L, "unexpected token in directive");
- getLexer().Lex();
+ Parser.Lex();
}
}
- getLexer().Lex();
+ Parser.Lex();
return false;
}
+extern "C" void LLVMInitializeX86AsmLexer();
+
// Force static initialization.
extern "C" void LLVMInitializeX86AsmParser() {
RegisterAsmParser<X86ATTAsmParser> X(TheX86_32Target);
RegisterAsmParser<X86ATTAsmParser> Y(TheX86_64Target);
+ LLVMInitializeX86AsmLexer();
}
#include "X86GenAsmMatcher.inc"
diff --git a/lib/Target/X86/AsmPrinter/Makefile b/lib/Target/X86/AsmPrinter/Makefile
index 2368761..326a22f 100644
--- a/lib/Target/X86/AsmPrinter/Makefile
+++ b/lib/Target/X86/AsmPrinter/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMX86AsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' x86 target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
index c74b97a..804dbb9 100644
--- a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
@@ -55,7 +55,7 @@ void X86ATTInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo) {
O << (int)Op.getImm();
else {
assert(Op.isExpr() && "unknown pcrel immediate operand");
- Op.getExpr()->print(O, &MAI);
+ O << *Op.getExpr();
}
}
@@ -68,8 +68,7 @@ void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo) {
O << '$' << Op.getImm();
} else {
assert(Op.isExpr() && "unknown operand kind in printOperand");
- O << '$';
- Op.getExpr()->print(O, &MAI);
+ O << '$' << *Op.getExpr();
}
}
@@ -84,7 +83,7 @@ void X86ATTInstPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) {
O << DispVal;
} else {
assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
- DispSpec.getExpr()->print(O, &MAI);
+ O << *DispSpec.getExpr();
}
if (IndexReg.getReg() || BaseReg.getReg()) {
diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
index 70c6dd0..2ffa18f 100644
--- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
@@ -36,7 +36,6 @@
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetOptions.h"
@@ -61,7 +60,7 @@ void X86AsmPrinter::printMCInst(const MCInst *MI) {
void X86AsmPrinter::PrintPICBaseSymbol() const {
// FIXME: Gross const cast hack.
X86AsmPrinter *AP = const_cast<X86AsmPrinter*>(this);
- X86MCInstLower(OutContext, 0, *AP).GetPICBaseSymbol()->print(O, MAI);
+ O << *X86MCInstLower(OutContext, 0, *AP).GetPICBaseSymbol();
}
void X86AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
@@ -71,7 +70,8 @@ void X86AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
if (Subtarget->isTargetCygMing()) {
X86COFFMachineModuleInfo &COFFMMI =
MMI->getObjFileInfo<X86COFFMachineModuleInfo>();
- COFFMMI.DecorateCygMingName(CurrentFnName, F, *TM.getTargetData());
+ COFFMMI.DecorateCygMingName(CurrentFnSym, OutContext, F,
+ *TM.getTargetData());
}
OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
@@ -84,7 +84,7 @@ void X86AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
break;
case Function::DLLExportLinkage:
case Function::ExternalLinkage:
- O << "\t.globl\t" << CurrentFnName << '\n';
+ OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_Global);
break;
case Function::LinkerPrivateLinkage:
case Function::LinkOnceAnyLinkage:
@@ -92,30 +92,30 @@ void X86AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
if (Subtarget->isTargetDarwin()) {
- O << "\t.globl\t" << CurrentFnName << '\n';
- O << MAI->getWeakDefDirective() << CurrentFnName << '\n';
+ OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_Global);
+ O << MAI->getWeakDefDirective() << *CurrentFnSym << '\n';
} else if (Subtarget->isTargetCygMing()) {
- O << "\t.globl\t" << CurrentFnName << "\n"
- "\t.linkonce discard\n";
+ OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_Global);
+ O << "\t.linkonce discard\n";
} else {
- O << "\t.weak\t" << CurrentFnName << '\n';
+ O << "\t.weak\t" << *CurrentFnSym << '\n';
}
break;
}
- printVisibility(CurrentFnName, F->getVisibility());
+ printVisibility(CurrentFnSym, F->getVisibility());
- if (Subtarget->isTargetELF())
- O << "\t.type\t" << CurrentFnName << ",@function\n";
- else if (Subtarget->isTargetCygMing()) {
- O << "\t.def\t " << CurrentFnName
- << ";\t.scl\t" <<
+ if (Subtarget->isTargetELF()) {
+ O << "\t.type\t" << *CurrentFnSym << ",@function\n";
+ } else if (Subtarget->isTargetCygMing()) {
+ O << "\t.def\t " << *CurrentFnSym;
+ O << ";\t.scl\t" <<
(F->hasInternalLinkage() ? COFF::C_STAT : COFF::C_EXT)
<< ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT)
<< ";\t.endef\n";
}
- O << CurrentFnName << ':';
+ O << *CurrentFnSym << ':';
if (VerboseAsm) {
O.PadToColumn(MAI->getCommentColumn());
O << MAI->getCommentString() << ' ';
@@ -126,7 +126,7 @@ void X86AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
// Add some workaround for linkonce linkage on Cygwin\MinGW
if (Subtarget->isTargetCygMing() &&
(F->hasLinkOnceLinkage() || F->hasWeakLinkage()))
- O << "Lllvm$workaround$fake$stub$" << CurrentFnName << ":\n";
+ O << "Lllvm$workaround$fake$stub$" << *CurrentFnSym << ":\n";
}
/// runOnMachineFunction - This uses the printMachineInstruction()
@@ -184,7 +184,7 @@ bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n';
+ O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
// Emit post-function debug information.
if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling())
@@ -201,93 +201,78 @@ bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
/// jump tables, constant pools, global address and external symbols, all of
/// which print to a label with various suffixes for relocation types etc.
void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
- SmallString<128> TempNameStr;
switch (MO.getType()) {
default: llvm_unreachable("unknown symbol type!");
case MachineOperand::MO_JumpTableIndex:
- O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
- << MO.getIndex();
+ O << *GetJTISymbol(MO.getIndex());
break;
case MachineOperand::MO_ConstantPoolIndex:
- O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
- << MO.getIndex();
+ O << *GetCPISymbol(MO.getIndex());
printOffset(MO.getOffset());
break;
case MachineOperand::MO_GlobalAddress: {
const GlobalValue *GV = MO.getGlobal();
- const char *Suffix = "";
+ MCSymbol *GVSym;
if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB)
- Suffix = "$stub";
+ GVSym = GetSymbolWithGlobalValueBase(GV, "$stub");
else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
- Suffix = "$non_lazy_ptr";
-
- std::string Name = Mang->getMangledName(GV, Suffix, Suffix[0] != '\0');
+ GVSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
+ else
+ GVSym = GetGlobalValueSymbol(GV);
+
if (Subtarget->isTargetCygMing()) {
X86COFFMachineModuleInfo &COFFMMI =
MMI->getObjFileInfo<X86COFFMachineModuleInfo>();
- COFFMMI.DecorateCygMingName(Name, GV, *TM.getTargetData());
+ COFFMMI.DecorateCygMingName(GVSym, OutContext, GV, *TM.getTargetData());
}
// Handle dllimport linkage.
if (MO.getTargetFlags() == X86II::MO_DLLIMPORT)
- Name = "__imp_" + Name;
+ GVSym = OutContext.GetOrCreateSymbol(Twine("__imp_") + GVSym->getName());
if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) {
- Mang->getNameWithPrefix(TempNameStr, GV, true);
- TempNameStr += "$non_lazy_ptr";
- MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str());
+ MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
const MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(Sym);
- if (StubSym == 0) {
- TempNameStr.clear();
- Mang->getNameWithPrefix(TempNameStr, GV, false);
- StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str());
- }
+ if (StubSym == 0)
+ StubSym = GetGlobalValueSymbol(GV);
+
} else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){
- Mang->getNameWithPrefix(TempNameStr, GV, true);
- TempNameStr += "$non_lazy_ptr";
- MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str());
+ MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
const MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getHiddenGVStubEntry(Sym);
- if (StubSym == 0) {
- TempNameStr.clear();
- Mang->getNameWithPrefix(TempNameStr, GV, false);
- StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str());
- }
+ if (StubSym == 0)
+ StubSym = GetGlobalValueSymbol(GV);
} else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
- Mang->getNameWithPrefix(TempNameStr, GV, true);
- TempNameStr += "$stub";
- MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str());
+ MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$stub");
const MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
- if (StubSym == 0) {
- TempNameStr.clear();
- Mang->getNameWithPrefix(TempNameStr, GV, false);
- StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str());
- }
+ if (StubSym == 0)
+ StubSym = GetGlobalValueSymbol(GV);
}
// If the name begins with a dollar-sign, enclose it in parens. We do this
// to avoid having it look like an integer immediate to the assembler.
- if (Name[0] == '$')
- O << '(' << Name << ')';
+ if (GVSym->getName()[0] != '$')
+ O << *GVSym;
else
- O << Name;
-
+ O << '(' << *GVSym << ')';
printOffset(MO.getOffset());
break;
}
case MachineOperand::MO_ExternalSymbol: {
const MCSymbol *SymToPrint;
if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
- Mang->getNameWithPrefix(TempNameStr,
- StringRef(MO.getSymbolName())+"$stub");
- const MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str());
+ SmallString<128> TempNameStr;
+ TempNameStr += StringRef(MO.getSymbolName());
+ TempNameStr += StringRef("$stub");
+
+ const MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str());
const MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
if (StubSym == 0) {
@@ -296,19 +281,15 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
}
SymToPrint = StubSym;
} else {
- Mang->getNameWithPrefix(TempNameStr, MO.getSymbolName());
- SymToPrint = OutContext.GetOrCreateSymbol(TempNameStr.str());
+ SymToPrint = GetExternalSymbolSymbol(MO.getSymbolName());
}
// If the name begins with a dollar-sign, enclose it in parens. We do this
// to avoid having it look like an integer immediate to the assembler.
if (SymToPrint->getName()[0] != '$')
- SymToPrint->print(O, MAI);
- else {
- O << '(';
- SymToPrint->print(O, MAI);
- O << '(';
- }
+ O << *SymToPrint;
+ else
+ O << '(' << *SymToPrint << '(';
break;
}
}
@@ -357,7 +338,7 @@ void X86AsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_GlobalAddress:
case MachineOperand::MO_ExternalSymbol:
@@ -368,7 +349,7 @@ void X86AsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
void X86AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
- const char *Modifier) {
+ const char *Modifier) {
const MachineOperand &MO = MI->getOperand(OpNo);
switch (MO.getType()) {
default: llvm_unreachable("unknown operand type!");
@@ -482,11 +463,10 @@ void X86AsmPrinter::printPICJumpTableSetLabel(unsigned uid,
O << MAI->getSetDirective() << ' ' << MAI->getPrivateGlobalPrefix()
<< getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ',';
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MBB->getNumber());
if (Subtarget->isPICStyleRIPRel())
- O << '-' << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
- << '_' << uid << '\n';
+ O << '-' << *GetJTISymbol(uid) << '\n';
else {
O << '-';
PrintPICBaseSymbol();
@@ -513,11 +493,10 @@ void X86AsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI,
if (Subtarget->isPICStyleRIPRel() || Subtarget->isPICStyleStubPIC()) {
O << MAI->getPrivateGlobalPrefix() << getFunctionNumber()
<< '_' << uid << "_set_" << MBB->getNumber();
- } else if (Subtarget->isPICStyleGOT()) {
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
- O << "@GOTOFF";
- } else
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
+ } else if (Subtarget->isPICStyleGOT())
+ O << *GetMBBSymbol(MBB->getNumber()) << "@GOTOFF";
+ else
+ O << *GetMBBSymbol(MBB->getNumber());
}
bool X86AsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode) {
@@ -664,147 +643,6 @@ void X86AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
processDebugLoc(MI, false);
}
-void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
- if (!GVar->hasInitializer())
- return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar)) {
- if (Subtarget->isTargetDarwin() &&
- TM.getRelocationModel() == Reloc::Static) {
- if (GVar->getName() == "llvm.global_ctors")
- O << ".reference .constructors_used\n";
- else if (GVar->getName() == "llvm.global_dtors")
- O << ".reference .destructors_used\n";
- }
- return;
- }
-
- const TargetData *TD = TM.getTargetData();
-
- std::string name = Mang->getMangledName(GVar);
- Constant *C = GVar->getInitializer();
- const Type *Type = C->getType();
- unsigned Size = TD->getTypeAllocSize(Type);
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
-
- printVisibility(name, GVar->getVisibility());
-
- if (Subtarget->isTargetELF())
- O << "\t.type\t" << name << ",@object\n";
-
-
- SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
- const MCSection *TheSection =
- getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
- OutStreamer.SwitchSection(TheSection);
-
- // FIXME: get this stuff from section kind flags.
- if (C->isNullValue() && !GVar->hasSection() &&
- // Don't put things that should go in the cstring section into "comm".
- !TheSection->getKind().isMergeableCString()) {
- if (GVar->hasExternalLinkage()) {
- if (const char *Directive = MAI->getZeroFillDirective()) {
- O << "\t.globl " << name << '\n';
- O << Directive << "__DATA, __common, " << name << ", "
- << Size << ", " << Align << '\n';
- return;
- }
- }
-
- if (!GVar->isThreadLocal() &&
- (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (MAI->getLCOMMDirective() != NULL) {
- if (GVar->hasLocalLinkage()) {
- O << MAI->getLCOMMDirective() << name << ',' << Size;
- if (Subtarget->isTargetDarwin())
- O << ',' << Align;
- } else if (Subtarget->isTargetDarwin() && !GVar->hasCommonLinkage()) {
- O << "\t.globl " << name << '\n'
- << MAI->getWeakDefDirective() << name << '\n';
- EmitAlignment(Align, GVar);
- O << name << ":";
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- EmitGlobalConstant(C);
- return;
- } else {
- O << MAI->getCOMMDirective() << name << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
- }
- } else {
- if (!Subtarget->isTargetCygMing()) {
- if (GVar->hasLocalLinkage())
- O << "\t.local\t" << name << '\n';
- }
- O << MAI->getCOMMDirective() << name << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
- }
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- return;
- }
- }
-
- switch (GVar->getLinkage()) {
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- if (Subtarget->isTargetDarwin()) {
- O << "\t.globl " << name << '\n'
- << MAI->getWeakDefDirective() << name << '\n';
- } else if (Subtarget->isTargetCygMing()) {
- O << "\t.globl\t" << name << "\n"
- "\t.linkonce same_size\n";
- } else {
- O << "\t.weak\t" << name << '\n';
- }
- break;
- case GlobalValue::DLLExportLinkage:
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << "\t.globl " << name << '\n';
- // FALL THROUGH
- case GlobalValue::PrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
- O << name << ":";
- if (VerboseAsm){
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
-
- EmitGlobalConstant(C);
-
- if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << name << ", " << Size << '\n';
-}
-
void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
if (Subtarget->isTargetDarwin()) {
// All darwin targets use mach-o.
@@ -828,10 +666,9 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
OutStreamer.SwitchSection(TheSection);
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- Stubs[i].first->print(O, MAI);
- O << ":\n" << "\t.indirect_symbol ";
+ O << *Stubs[i].first << ":\n";
// Get the MCSymbol without the $stub suffix.
- Stubs[i].second->print(O, MAI);
+ O << "\t.indirect_symbol " << *Stubs[i].second;
O << "\n\thlt ; hlt ; hlt ; hlt ; hlt\n";
}
O << '\n';
@@ -849,9 +686,7 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
OutStreamer.SwitchSection(TheSection);
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- Stubs[i].first->print(O, MAI);
- O << ":\n\t.indirect_symbol ";
- Stubs[i].second->print(O, MAI);
+ O << *Stubs[i].first << ":\n\t.indirect_symbol " << *Stubs[i].second;
O << "\n\t.long\t0\n";
}
Stubs.clear();
@@ -863,10 +698,8 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
EmitAlignment(2);
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- Stubs[i].first->print(O, MAI);
- O << ":\n" << MAI->getData32bitsDirective();
- Stubs[i].second->print(O, MAI);
- O << '\n';
+ O << *Stubs[i].first << ":\n" << MAI->getData32bitsDirective();
+ O << *Stubs[i].second << '\n';
}
Stubs.clear();
}
@@ -876,7 +709,7 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
// implementation of multiple entry points). If this doesn't occur, the
// linker can safely perform dead code stripping. Since LLVM never
// generates code that does this, it is always safe to set.
- OutStreamer.EmitAssemblerFlag(MCStreamer::SubsectionsViaSymbols);
+ OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
}
if (Subtarget->isTargetCOFF()) {
@@ -894,25 +727,22 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
if (Subtarget->isTargetCygMing()) {
// Necessary for dllexport support
- std::vector<std::string> DLLExportedFns, DLLExportedGlobals;
+ std::vector<const MCSymbol*> DLLExportedFns, DLLExportedGlobals;
TargetLoweringObjectFileCOFF &TLOFCOFF =
static_cast<TargetLoweringObjectFileCOFF&>(getObjFileLowering());
for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
if (I->hasDLLExportLinkage()) {
- std::string Name = Mang->getMangledName(I);
- COFFMMI.DecorateCygMingName(Name, I, *TM.getTargetData());
- DLLExportedFns.push_back(Name);
+ MCSymbol *Sym = GetGlobalValueSymbol(I);
+ COFFMMI.DecorateCygMingName(Sym, OutContext, I, *TM.getTargetData());
+ DLLExportedFns.push_back(Sym);
}
for (Module::const_global_iterator I = M.global_begin(),
E = M.global_end(); I != E; ++I)
- if (I->hasDLLExportLinkage()) {
- std::string Name = Mang->getMangledName(I);
- COFFMMI.DecorateCygMingName(Name, I, *TM.getTargetData());
- DLLExportedGlobals.push_back(Mang->getMangledName(I));
- }
+ if (I->hasDLLExportLinkage())
+ DLLExportedGlobals.push_back(GetGlobalValueSymbol(I));
// Output linker support code for dllexported globals on windows.
if (!DLLExportedGlobals.empty() || !DLLExportedFns.empty()) {
@@ -920,10 +750,10 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
true,
SectionKind::getMetadata()));
for (unsigned i = 0, e = DLLExportedGlobals.size(); i != e; ++i)
- O << "\t.ascii \" -export:" << DLLExportedGlobals[i] << ",data\"\n";
+ O << "\t.ascii \" -export:" << *DLLExportedGlobals[i] << ",data\"\n";
for (unsigned i = 0, e = DLLExportedFns.size(); i != e; ++i)
- O << "\t.ascii \" -export:" << DLLExportedFns[i] << "\"\n";
+ O << "\t.ascii \" -export:" << *DLLExportedFns[i] << "\"\n";
}
}
}
diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.h b/lib/Target/X86/AsmPrinter/X86AsmPrinter.h
index 0351829..6a9262d 100644
--- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.h
+++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.h
@@ -135,7 +135,6 @@ class VISIBILITY_HIDDEN X86AsmPrinter : public AsmPrinter {
unsigned uid) const;
void printPICLabel(const MachineInstr *MI, unsigned Op);
- void PrintGlobalVariable(const GlobalVariable* GVar);
void PrintPICBaseSymbol() const;
diff --git a/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp
index fde5902..4efb529 100644
--- a/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp
@@ -52,7 +52,7 @@ void X86IntelInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo) {
O << Op.getImm();
else {
assert(Op.isExpr() && "unknown pcrel immediate operand");
- Op.getExpr()->print(O, &MAI);
+ O << *Op.getExpr();
}
}
@@ -72,7 +72,7 @@ void X86IntelInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
O << Op.getImm();
} else {
assert(Op.isExpr() && "unknown operand kind in printOperand");
- Op.getExpr()->print(O, &MAI);
+ O << *Op.getExpr();
}
}
@@ -102,7 +102,7 @@ void X86IntelInstPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) {
if (!DispSpec.isImm()) {
if (NeedPlus) O << " + ";
assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
- DispSpec.getExpr()->print(O, &MAI);
+ O << *DispSpec.getExpr();
} else {
int64_t DispVal = DispSpec.getImm();
if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) {
diff --git a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
index 9ee118c..b970d46 100644
--- a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
+++ b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
@@ -16,16 +16,15 @@
#include "X86AsmPrinter.h"
#include "X86MCAsmInfo.h"
#include "X86COFFMachineModuleInfo.h"
+#include "llvm/Analysis/DebugInfo.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCStreamer.h"
-#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/Analysis/DebugInfo.h"
using namespace llvm;
@@ -83,33 +82,24 @@ GetGlobalAddressSymbol(const MachineOperand &MO) const {
MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
const MCSymbol *&StubSym = getMachOMMI().getGVStubEntry(Sym);
- if (StubSym == 0) {
- Name.clear();
- Mang->getNameWithPrefix(Name, GV, false);
- StubSym = Ctx.GetOrCreateSymbol(Name.str());
- }
+ if (StubSym == 0)
+ StubSym = AsmPrinter.GetGlobalValueSymbol(GV);
return Sym;
}
case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: {
Name += "$non_lazy_ptr";
MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
const MCSymbol *&StubSym = getMachOMMI().getHiddenGVStubEntry(Sym);
- if (StubSym == 0) {
- Name.clear();
- Mang->getNameWithPrefix(Name, GV, false);
- StubSym = Ctx.GetOrCreateSymbol(Name.str());
- }
+ if (StubSym == 0)
+ StubSym = AsmPrinter.GetGlobalValueSymbol(GV);
return Sym;
}
case X86II::MO_DARWIN_STUB: {
Name += "$stub";
MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
const MCSymbol *&StubSym = getMachOMMI().getFnStubEntry(Sym);
- if (StubSym == 0) {
- Name.clear();
- Mang->getNameWithPrefix(Name, GV, false);
- StubSym = Ctx.GetOrCreateSymbol(Name.str());
- }
+ if (StubSym == 0)
+ StubSym = AsmPrinter.GetGlobalValueSymbol(GV);
return Sym;
}
// FIXME: These probably should be a modifier on the symbol or something??
@@ -173,6 +163,8 @@ GetExternalSymbolSymbol(const MachineOperand &MO) const {
MCSymbol *X86MCInstLower::GetJumpTableSymbol(const MachineOperand &MO) const {
SmallString<256> Name;
+ // FIXME: Use AsmPrinter.GetJTISymbol. @TLSGD shouldn't be part of the symbol
+ // name!
raw_svector_ostream(Name) << AsmPrinter.MAI->getPrivateGlobalPrefix() << "JTI"
<< AsmPrinter.getFunctionNumber() << '_' << MO.getIndex();
@@ -204,6 +196,8 @@ MCSymbol *X86MCInstLower::GetJumpTableSymbol(const MachineOperand &MO) const {
MCSymbol *X86MCInstLower::
GetConstantPoolIndexSymbol(const MachineOperand &MO) const {
SmallString<256> Name;
+ // FIXME: USe AsmPrinter.GetCPISymbol. @TLSGD shouldn't be part of the symbol
+ // name!
raw_svector_ostream(Name) << AsmPrinter.MAI->getPrivateGlobalPrefix() << "CPI"
<< AsmPrinter.getFunctionNumber() << '_' << MO.getIndex();
@@ -422,22 +416,28 @@ void X86AsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
printLabel(MI);
return;
case TargetInstrInfo::DEBUG_VALUE: {
+ // FIXME: if this is implemented for another target before it goes
+ // away completely, the common part should be moved into AsmPrinter.
if (!VerboseAsm)
return;
O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
- // cast away const; DIetc do not take const operands for some reason
- DIVariable V((MDNode*)(MI->getOperand(2).getMetadata()));
+ unsigned NOps = MI->getNumOperands();
+ // cast away const; DIetc do not take const operands for some reason.
+ DIVariable V((MDNode*)(MI->getOperand(NOps-1).getMetadata()));
O << V.getName();
O << " <- ";
- if (MI->getOperand(0).getType()==MachineOperand::MO_Register)
+ if (NOps==3) {
+ // Variable is in register
+ assert(MI->getOperand(0).getType()==MachineOperand::MO_Register);
printOperand(MI, 0);
- else {
- assert(MI->getOperand(0).getType()==MachineOperand::MO_Immediate);
- int64_t imm = MI->getOperand(0).getImm();
- O << '[' << ((imm<0) ? "EBP" : "ESP+") << imm << ']';
+ } else {
+ // Frame address. Currently handles register +- offset only.
+ assert(MI->getOperand(0).getType()==MachineOperand::MO_Register);
+ assert(MI->getOperand(3).getType()==MachineOperand::MO_Immediate);
+ O << '['; printOperand(MI, 0); O << '+'; printOperand(MI, 3); O << ']';
}
O << "+";
- printOperand(MI, 1);
+ printOperand(MI, NOps-2);
return;
}
case TargetInstrInfo::INLINEASM:
diff --git a/lib/Target/X86/Disassembler/Makefile b/lib/Target/X86/Disassembler/Makefile
index b289647..6c26853 100644
--- a/lib/Target/X86/Disassembler/Makefile
+++ b/lib/Target/X86/Disassembler/Makefile
@@ -9,6 +9,7 @@
LEVEL = ../../../..
LIBRARYNAME = LLVMX86Disassembler
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' x86 target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/X86/Makefile b/lib/Target/X86/Makefile
index 6098dbf..5e625dc 100644
--- a/lib/Target/X86/Makefile
+++ b/lib/Target/X86/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMX86CodeGen
TARGET = X86
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = X86GenRegisterInfo.h.inc X86GenRegisterNames.inc \
diff --git a/lib/Target/X86/TargetInfo/Makefile b/lib/Target/X86/TargetInfo/Makefile
index 6677d4b..211607f 100644
--- a/lib/Target/X86/TargetInfo/Makefile
+++ b/lib/Target/X86/TargetInfo/Makefile
@@ -6,8 +6,10 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../../..
LIBRARYNAME = LLVMX86Info
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/X86/X86COFFMachineModuleInfo.cpp b/lib/Target/X86/X86COFFMachineModuleInfo.cpp
index 01c4fcf..ea52795 100644
--- a/lib/Target/X86/X86COFFMachineModuleInfo.cpp
+++ b/lib/Target/X86/X86COFFMachineModuleInfo.cpp
@@ -15,6 +15,8 @@
#include "X86MachineFunctionInfo.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/TargetData.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"
@@ -23,7 +25,6 @@ using namespace llvm;
X86COFFMachineModuleInfo::X86COFFMachineModuleInfo(const MachineModuleInfo &) {
}
X86COFFMachineModuleInfo::~X86COFFMachineModuleInfo() {
-
}
void X86COFFMachineModuleInfo::AddFunctionInfo(const Function *F,
@@ -114,10 +115,12 @@ void X86COFFMachineModuleInfo::DecorateCygMingName(SmallVectorImpl<char> &Name,
/// DecorateCygMingName - Query FunctionInfoMap and use this information for
/// various name decorations for Cygwin and MingW.
-void X86COFFMachineModuleInfo::DecorateCygMingName(std::string &Name,
+void X86COFFMachineModuleInfo::DecorateCygMingName(MCSymbol *&Name,
+ MCContext &Ctx,
const GlobalValue *GV,
const TargetData &TD) {
- SmallString<128> NameStr(Name.begin(), Name.end());
+ SmallString<128> NameStr(Name->getName().begin(), Name->getName().end());
DecorateCygMingName(NameStr, GV, TD);
- Name.assign(NameStr.begin(), NameStr.end());
+
+ Name = Ctx.GetOrCreateSymbol(NameStr.str());
}
diff --git a/lib/Target/X86/X86COFFMachineModuleInfo.h b/lib/Target/X86/X86COFFMachineModuleInfo.h
index 5017af2..0e2009e 100644
--- a/lib/Target/X86/X86COFFMachineModuleInfo.h
+++ b/lib/Target/X86/X86COFFMachineModuleInfo.h
@@ -46,8 +46,8 @@ public:
~X86COFFMachineModuleInfo();
- void DecorateCygMingName(std::string &Name, const GlobalValue *GV,
- const TargetData &TD);
+ void DecorateCygMingName(MCSymbol* &Name, MCContext &Ctx,
+ const GlobalValue *GV, const TargetData &TD);
void DecorateCygMingName(SmallVectorImpl<char> &Name, const GlobalValue *GV,
const TargetData &TD);
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index 7e02d59..d5ad61b 100644
--- a/lib/Target/X86/X86FastISel.cpp
+++ b/lib/Target/X86/X86FastISel.cpp
@@ -1153,6 +1153,10 @@ bool X86FastISel::X86VisitIntrinsicCall(IntrinsicInst &I) {
// FIXME: Handle more intrinsics.
switch (I.getIntrinsicID()) {
default: return false;
+ case Intrinsic::trap: {
+ BuildMI(MBB, DL, TII.get(X86::TRAP));
+ return true;
+ }
case Intrinsic::sadd_with_overflow:
case Intrinsic::uadd_with_overflow: {
// Replace "add with overflow" intrinsics with an "add" instruction followed
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index e2a53d1..91e0483 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -384,8 +384,11 @@ static void MoveBelowTokenFactor(SelectionDAG *CurDAG, SDValue Load,
///
static bool isRMWLoad(SDValue N, SDValue Chain, SDValue Address,
SDValue &Load) {
- if (N.getOpcode() == ISD::BIT_CONVERT)
+ if (N.getOpcode() == ISD::BIT_CONVERT) {
+ if (!N.hasOneUse())
+ return false;
N = N.getOperand(0);
+ }
LoadSDNode *LD = dyn_cast<LoadSDNode>(N);
if (!LD || LD->isVolatile())
@@ -595,6 +598,7 @@ void X86DAGToDAGISel::PreprocessForRMW() {
if (RModW) {
MoveBelowTokenFactor(CurDAG, Load, SDValue(I, 0), Chain);
++NumLoadMoved;
+ checkForCycles(I);
}
}
}
@@ -940,7 +944,7 @@ bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
// Okay, we know that we have a scale by now. However, if the scaled
// value is an add of something and a constant, we can fold the
// constant into the disp field here.
- if (ShVal.getNode()->getOpcode() == ISD::ADD && ShVal.hasOneUse() &&
+ if (ShVal.getNode()->getOpcode() == ISD::ADD &&
isa<ConstantSDNode>(ShVal.getNode()->getOperand(1))) {
AM.IndexReg = ShVal.getNode()->getOperand(0);
ConstantSDNode *AddVal =
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 228ec9f..11e07df 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -3390,17 +3390,10 @@ X86TargetLowering::LowerAsSplatVectorLoad(SDValue SrcOp, EVT VT, DebugLoc dl,
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
if (DAG.InferPtrAlignment(Ptr) < 16) {
if (MFI->isFixedObjectIndex(FI)) {
- // Can't change the alignment. Reference stack + offset explicitly
- // if stack pointer is at least 16-byte aligned.
- unsigned StackAlign = Subtarget->getStackAlignment();
- if (StackAlign < 16)
- return SDValue();
- Offset = MFI->getObjectOffset(FI) + Offset;
- SDValue StackPtr = DAG.getCopyFromReg(Chain, dl, X86StackPtr,
- getPointerTy());
- Ptr = DAG.getNode(ISD::ADD, dl, getPointerTy(), StackPtr,
- DAG.getConstant(Offset & ~15, getPointerTy()));
- Offset %= 16;
+ // Can't change the alignment. FIXME: It's possible to compute
+ // the exact stack offset and reference FI + adjust offset instead.
+ // If someone *really* cares about this. That's the way to implement it.
+ return SDValue();
} else {
MFI->setObjectAlignment(FI, 16);
}
@@ -7579,7 +7572,7 @@ bool X86TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
bool X86TargetLowering::isZExtFree(const Type *Ty1, const Type *Ty2) const {
// x86-64 implicitly zero-extends 32-bit results in 64-bit registers.
- return Ty1->isInteger(64) && Ty2->isInteger(64) && Subtarget->is64Bit();
+ return Ty1->isInteger(32) && Ty2->isInteger(64) && Subtarget->is64Bit();
}
bool X86TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td
index 08e1dd1..9037ba6 100644
--- a/lib/Target/X86/X86Instr64bit.td
+++ b/lib/Target/X86/X86Instr64bit.td
@@ -207,7 +207,7 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
// EH Pseudo Instructions
//
let isTerminator = 1, isReturn = 1, isBarrier = 1,
- hasCtrlDep = 1 in {
+ hasCtrlDep = 1, isCodeGenOnly = 1 in {
def EH_RETURN64 : I<0xC3, RawFrm, (outs), (ins GR64:$addr),
"ret\t#eh_return, addr: $addr",
[(X86ehret GR64:$addr)]>;
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
index 7b39fb3..3ae352c 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -402,7 +402,7 @@ X86InstrInfo::X86InstrInfo(X86TargetMachine &tm)
{ X86::MOVSX64rr32, X86::MOVSX64rm32, 0 },
{ X86::MOVSX64rr8, X86::MOVSX64rm8, 0 },
{ X86::MOVUPDrr, X86::MOVUPDrm, 16 },
- { X86::MOVUPSrr, X86::MOVUPSrm, 16 },
+ { X86::MOVUPSrr, X86::MOVUPSrm, 0 },
{ X86::MOVZDI2PDIrr, X86::MOVZDI2PDIrm, 0 },
{ X86::MOVZQI2PQIrr, X86::MOVZQI2PQIrm, 0 },
{ X86::MOVZPQILo2PQIrr, X86::MOVZPQILo2PQIrm, 16 },
@@ -2077,8 +2077,7 @@ void X86InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
unsigned SrcReg, bool isKill, int FrameIdx,
const TargetRegisterClass *RC) const {
const MachineFunction &MF = *MBB.getParent();
- bool isAligned = (RI.getStackAlignment() >= 16) ||
- RI.needsStackRealignment(MF);
+ bool isAligned = (RI.getStackAlignment() >= 16) || RI.canRealignStack(MF);
unsigned Opc = getStoreRegOpcode(SrcReg, RC, isAligned, TM);
DebugLoc DL = DebugLoc::getUnknownLoc();
if (MI != MBB.end()) DL = MI->getDebugLoc();
@@ -2172,8 +2171,7 @@ void X86InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
unsigned DestReg, int FrameIdx,
const TargetRegisterClass *RC) const{
const MachineFunction &MF = *MBB.getParent();
- bool isAligned = (RI.getStackAlignment() >= 16) ||
- RI.needsStackRealignment(MF);
+ bool isAligned = (RI.getStackAlignment() >= 16) || RI.canRealignStack(MF);
unsigned Opc = getLoadRegOpcode(DestReg, RC, isAligned, TM);
DebugLoc DL = DebugLoc::getUnknownLoc();
if (MI != MBB.end()) DL = MI->getDebugLoc();
@@ -2202,8 +2200,7 @@ bool X86InstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
if (CSI.empty())
return false;
- DebugLoc DL = DebugLoc::getUnknownLoc();
- if (MI != MBB.end()) DL = MI->getDebugLoc();
+ DebugLoc DL = MBB.findDebugLoc(MI);
bool is64Bit = TM.getSubtarget<X86Subtarget>().is64Bit();
bool isWin64 = TM.getSubtarget<X86Subtarget>().isTargetWin64();
@@ -2241,8 +2238,7 @@ bool X86InstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
if (CSI.empty())
return false;
- DebugLoc DL = DebugLoc::getUnknownLoc();
- if (MI != MBB.end()) DL = MI->getDebugLoc();
+ DebugLoc DL = MBB.findDebugLoc(MI);
MachineFunction &MF = *MBB.getParent();
unsigned FPReg = RI.getFrameRegister(MF);
@@ -2872,6 +2868,138 @@ unsigned X86InstrInfo::getOpcodeAfterMemoryUnfold(unsigned Opc,
return I->second.first;
}
+bool
+X86InstrInfo::areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
+ int64_t &Offset1, int64_t &Offset2) const {
+ if (!Load1->isMachineOpcode() || !Load2->isMachineOpcode())
+ return false;
+ unsigned Opc1 = Load1->getMachineOpcode();
+ unsigned Opc2 = Load2->getMachineOpcode();
+ switch (Opc1) {
+ default: return false;
+ case X86::MOV8rm:
+ case X86::MOV16rm:
+ case X86::MOV32rm:
+ case X86::MOV64rm:
+ case X86::LD_Fp32m:
+ case X86::LD_Fp64m:
+ case X86::LD_Fp80m:
+ case X86::MOVSSrm:
+ case X86::MOVSDrm:
+ case X86::MMX_MOVD64rm:
+ case X86::MMX_MOVQ64rm:
+ case X86::FsMOVAPSrm:
+ case X86::FsMOVAPDrm:
+ case X86::MOVAPSrm:
+ case X86::MOVUPSrm:
+ case X86::MOVUPSrm_Int:
+ case X86::MOVAPDrm:
+ case X86::MOVDQArm:
+ case X86::MOVDQUrm:
+ case X86::MOVDQUrm_Int:
+ break;
+ }
+ switch (Opc2) {
+ default: return false;
+ case X86::MOV8rm:
+ case X86::MOV16rm:
+ case X86::MOV32rm:
+ case X86::MOV64rm:
+ case X86::LD_Fp32m:
+ case X86::LD_Fp64m:
+ case X86::LD_Fp80m:
+ case X86::MOVSSrm:
+ case X86::MOVSDrm:
+ case X86::MMX_MOVD64rm:
+ case X86::MMX_MOVQ64rm:
+ case X86::FsMOVAPSrm:
+ case X86::FsMOVAPDrm:
+ case X86::MOVAPSrm:
+ case X86::MOVUPSrm:
+ case X86::MOVUPSrm_Int:
+ case X86::MOVAPDrm:
+ case X86::MOVDQArm:
+ case X86::MOVDQUrm:
+ case X86::MOVDQUrm_Int:
+ break;
+ }
+
+ // Check if chain operands and base addresses match.
+ if (Load1->getOperand(0) != Load2->getOperand(0) ||
+ Load1->getOperand(5) != Load2->getOperand(5))
+ return false;
+ // Segment operands should match as well.
+ if (Load1->getOperand(4) != Load2->getOperand(4))
+ return false;
+ // Scale should be 1, Index should be Reg0.
+ if (Load1->getOperand(1) == Load2->getOperand(1) &&
+ Load1->getOperand(2) == Load2->getOperand(2)) {
+ if (cast<ConstantSDNode>(Load1->getOperand(1))->getZExtValue() != 1)
+ return false;
+ SDValue Op2 = Load1->getOperand(2);
+ if (!isa<RegisterSDNode>(Op2) ||
+ cast<RegisterSDNode>(Op2)->getReg() != 0)
+ return 0;
+
+ // Now let's examine the displacements.
+ if (isa<ConstantSDNode>(Load1->getOperand(3)) &&
+ isa<ConstantSDNode>(Load2->getOperand(3))) {
+ Offset1 = cast<ConstantSDNode>(Load1->getOperand(3))->getSExtValue();
+ Offset2 = cast<ConstantSDNode>(Load2->getOperand(3))->getSExtValue();
+ return true;
+ }
+ }
+ return false;
+}
+
+bool X86InstrInfo::shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
+ int64_t Offset1, int64_t Offset2,
+ unsigned NumLoads) const {
+ assert(Offset2 > Offset1);
+ if ((Offset2 - Offset1) / 8 > 64)
+ return false;
+
+ unsigned Opc1 = Load1->getMachineOpcode();
+ unsigned Opc2 = Load2->getMachineOpcode();
+ if (Opc1 != Opc2)
+ return false; // FIXME: overly conservative?
+
+ switch (Opc1) {
+ default: break;
+ case X86::LD_Fp32m:
+ case X86::LD_Fp64m:
+ case X86::LD_Fp80m:
+ case X86::MMX_MOVD64rm:
+ case X86::MMX_MOVQ64rm:
+ return false;
+ }
+
+ EVT VT = Load1->getValueType(0);
+ switch (VT.getSimpleVT().SimpleTy) {
+ default: {
+ // XMM registers. In 64-bit mode we can be a bit more aggressive since we
+ // have 16 of them to play with.
+ if (TM.getSubtargetImpl()->is64Bit()) {
+ if (NumLoads >= 3)
+ return false;
+ } else if (NumLoads)
+ return false;
+ break;
+ }
+ case MVT::i8:
+ case MVT::i16:
+ case MVT::i32:
+ case MVT::i64:
+ case MVT::f32:
+ case MVT::f64:
+ if (NumLoads)
+ return false;
+ }
+
+ return true;
+}
+
+
bool X86InstrInfo::
ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
assert(Cond.size() == 1 && "Invalid X86 branch condition!");
diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h
index 0ab85f4..4f35d0d 100644
--- a/lib/Target/X86/X86InstrInfo.h
+++ b/lib/Target/X86/X86InstrInfo.h
@@ -610,6 +610,26 @@ public:
bool UnfoldLoad, bool UnfoldStore,
unsigned *LoadRegIndex = 0) const;
+ /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler
+ /// to determine if two loads are loading from the same base address. It
+ /// should only return true if the base pointers are the same and the
+ /// only differences between the two addresses are the offset. It also returns
+ /// the offsets by reference.
+ virtual bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
+ int64_t &Offset1, int64_t &Offset2) const;
+
+ /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to
+ /// determine (in conjuction with areLoadsFromSameBasePtr) if two loads should
+ /// be scheduled togther. On some targets if two loads are loading from
+ /// addresses in the same cache line, it's better if they are scheduled
+ /// together. This function takes two integers that represent the load offsets
+ /// from the common base address. It returns true if it decides it's desirable
+ /// to schedule the two loads together. "NumLoads" is the number of loads that
+ /// have already been scheduled after Load1.
+ virtual bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
+ int64_t Offset1, int64_t Offset2,
+ unsigned NumLoads) const;
+
virtual
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
diff --git a/lib/Target/X86/X86MCAsmInfo.cpp b/lib/Target/X86/X86MCAsmInfo.cpp
index 9d7e66d..1738d49 100644
--- a/lib/Target/X86/X86MCAsmInfo.cpp
+++ b/lib/Target/X86/X86MCAsmInfo.cpp
@@ -14,6 +14,7 @@
#include "X86MCAsmInfo.h"
#include "X86TargetMachine.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/MC/MCSectionELF.h"
#include "llvm/Support/CommandLine.h"
using namespace llvm;
@@ -87,10 +88,11 @@ X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &Triple) {
// Exceptions handling
ExceptionsType = ExceptionHandling::Dwarf;
AbsoluteEHSectionOffsets = false;
+}
- // On Linux we must declare when we can use a non-executable stack.
- if (Triple.getOS() == Triple::Linux)
- NonexecutableStackDirective = "\t.section\t.note.GNU-stack,\"\",@progbits";
+MCSection *X86ELFMCAsmInfo::getNonexecutableStackSection(MCContext &Ctx) const {
+ return MCSectionELF::Create(".note.GNU-stack", MCSectionELF::SHT_PROGBITS,
+ 0, SectionKind::getMetadata(), false, Ctx);
}
X86MCAsmInfoCOFF::X86MCAsmInfoCOFF(const Triple &Triple) {
@@ -109,7 +111,6 @@ X86WinMCAsmInfo::X86WinMCAsmInfo(const Triple &Triple) {
PrivateGlobalPrefix = "$";
AlignDirective = "\tALIGN\t";
ZeroDirective = "\tdb\t";
- ZeroDirectiveSuffix = " dup(0)";
AsciiDirective = "\tdb\t";
AscizDirective = 0;
Data8bitsDirective = "\tdb\t";
diff --git a/lib/Target/X86/X86MCAsmInfo.h b/lib/Target/X86/X86MCAsmInfo.h
index 18e2bdb..ca227b7 100644
--- a/lib/Target/X86/X86MCAsmInfo.h
+++ b/lib/Target/X86/X86MCAsmInfo.h
@@ -27,6 +27,7 @@ namespace llvm {
struct X86ELFMCAsmInfo : public MCAsmInfo {
explicit X86ELFMCAsmInfo(const Triple &Triple);
+ virtual MCSection *getNonexecutableStackSection(MCContext &Ctx) const;
};
struct X86MCAsmInfoCOFF : public MCAsmInfoCOFF {
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
index 9bd96af..f959a2d 100644
--- a/lib/Target/X86/X86RegisterInfo.cpp
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -438,6 +438,12 @@ bool X86RegisterInfo::hasFP(const MachineFunction &MF) const {
(MMI && MMI->callsUnwindInit()));
}
+bool X86RegisterInfo::canRealignStack(const MachineFunction &MF) const {
+ const MachineFrameInfo *MFI = MF.getFrameInfo();
+ return (RealignStack &&
+ !MFI->hasVarSizedObjects());
+}
+
bool X86RegisterInfo::needsStackRealignment(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
bool requiresRealignment =
@@ -591,15 +597,6 @@ X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int FrameIndex = MI.getOperand(i).getIndex();
unsigned BasePtr;
- // DEBUG_VALUE has a special representation, and is only robust enough to
- // represent SP(or BP) +- offset addressing modes. We rewrite the
- // FrameIndex to be a constant; implicitly positive constants are relative
- // to ESP and negative ones to EBP.
- if (MI.getOpcode()==TargetInstrInfo::DEBUG_VALUE) {
- MI.getOperand(i).ChangeToImmediate(getFrameIndexOffset(MF, FrameIndex));
- return 0;
- }
-
if (needsStackRealignment(MF))
BasePtr = (FrameIndex < 0 ? FramePtr : StackPtr);
else
@@ -685,8 +682,7 @@ void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
(Is64Bit ? X86::ADD64ri8 : X86::ADD32ri8) :
(Is64Bit ? X86::ADD64ri32 : X86::ADD32ri));
uint64_t Chunk = (1LL << 31) - 1;
- DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() :
- DebugLoc::getUnknownLoc());
+ DebugLoc DL = MBB.findDebugLoc(MBBI);
while (Offset) {
uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset;
@@ -1035,8 +1031,7 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
}
}
- if (MBBI != MBB.end())
- DL = MBBI->getDebugLoc();
+ DL = MBB.findDebugLoc(MBBI);
// Adjust stack pointer: ESP -= numbytes.
if (NumBytes >= 4096 && Subtarget->isTargetCygMing()) {
diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h
index f281a3c..dec3fba 100644
--- a/lib/Target/X86/X86RegisterInfo.h
+++ b/lib/Target/X86/X86RegisterInfo.h
@@ -128,6 +128,8 @@ public:
bool hasFP(const MachineFunction &MF) const;
+ bool canRealignStack(const MachineFunction &MF) const;
+
bool needsStackRealignment(const MachineFunction &MF) const;
bool hasReservedCallFrame(MachineFunction &MF) const;
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index 962f0f7..731c3ab 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -157,9 +157,6 @@ bool X86TargetMachine::addInstSelector(PassManagerBase &PM,
bool X86TargetMachine::addPreRegAlloc(PassManagerBase &PM,
CodeGenOpt::Level OptLevel) {
- // Calculate and set max stack object alignment early, so we can decide
- // whether we will need stack realignment (and thus FP).
- PM.add(createMaxStackAlignmentCalculatorPass());
return false; // -print-machineinstr shouldn't print after this.
}
@@ -249,3 +246,32 @@ void X86TargetMachine::setCodeModelForJIT() {
else
setCodeModel(CodeModel::Small);
}
+
+/// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are 4-byte,
+/// 8-byte, and target default. The CIE is hard-coded to indicate that the LSDA
+/// pointer in the FDE section is an "sdata4", and should be encoded as a 4-byte
+/// pointer by default. However, some systems may require a different size due
+/// to bugs or other conditions. We will default to a 4-byte encoding unless the
+/// system tells us otherwise.
+///
+/// The issue is when the CIE says their is an LSDA. That mandates that every
+/// FDE have an LSDA slot. But if the function does not need an LSDA. There
+/// needs to be some way to signify there is none. The LSDA is encoded as
+/// pc-rel. But you don't look for some magic value after adding the pc. You
+/// have to look for a zero before adding the pc. The problem is that the size
+/// of the zero to look for depends on the encoding. The unwinder bug in SL is
+/// that it always checks for a pointer-size zero. So on x86_64 it looks for 8
+/// bytes of zero. If you have an LSDA, it works fine since the 8-bytes are
+/// non-zero so it goes ahead and then reads the value based on the encoding.
+/// But if you use sdata4 and there is no LSDA, then the test for zero gives a
+/// false negative and the unwinder thinks there is an LSDA.
+///
+/// FIXME: This call-back isn't good! We should be using the correct encoding
+/// regardless of the system. However, there are some systems which have bugs
+/// that prevent this from occuring.
+DwarfLSDAEncoding::Encoding X86TargetMachine::getLSDAEncoding() const {
+ if (Subtarget.isTargetDarwin() && Subtarget.getDarwinVers() != 10)
+ return DwarfLSDAEncoding::Default;
+
+ return DwarfLSDAEncoding::EightByte;
+}
diff --git a/lib/Target/X86/X86TargetMachine.h b/lib/Target/X86/X86TargetMachine.h
index 6183e91..d05bebd 100644
--- a/lib/Target/X86/X86TargetMachine.h
+++ b/lib/Target/X86/X86TargetMachine.h
@@ -62,6 +62,18 @@ public:
return Subtarget.isTargetELF() ? &ELFWriterInfo : 0;
}
+ /// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are
+ /// 4-byte, 8-byte, and target default. The CIE is hard-coded to indicate that
+ /// the LSDA pointer in the FDE section is an "sdata4", and should be encoded
+ /// as a 4-byte pointer by default. However, some systems may require a
+ /// different size due to bugs or other conditions. We will default to a
+ /// 4-byte encoding unless the system tells us otherwise.
+ ///
+ /// FIXME: This call-back isn't good! We should be using the correct encoding
+ /// regardless of the system. However, there are some systems which have bugs
+ /// that prevent this from occuring.
+ virtual DwarfLSDAEncoding::Encoding getLSDAEncoding() const;
+
// Set up the pass pipeline.
virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
virtual bool addPreRegAlloc(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
diff --git a/lib/Target/X86/X86TargetObjectFile.cpp b/lib/Target/X86/X86TargetObjectFile.cpp
index d39b3c4..41ad153 100644
--- a/lib/Target/X86/X86TargetObjectFile.cpp
+++ b/lib/Target/X86/X86TargetObjectFile.cpp
@@ -8,11 +8,11 @@
//===----------------------------------------------------------------------===//
#include "X86TargetObjectFile.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/Mangler.h"
+#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
-#include "llvm/CodeGen/MachineModuleInfoImpls.h"
+#include "llvm/Target/Mangler.h"
+#include "llvm/ADT/SmallString.h"
using namespace llvm;
const MCExpr *X8632_MachoTargetObjectFile::
@@ -27,6 +27,7 @@ getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
MachineModuleInfoMachO &MachOMMI =
MMI->getObjFileInfo<MachineModuleInfoMachO>();
+ // FIXME: Use GetSymbolWithGlobalValueBase.
SmallString<128> Name;
Mang->getNameWithPrefix(Name, GV, true);
Name += "$non_lazy_ptr";
diff --git a/lib/Target/XCore/AsmPrinter/Makefile b/lib/Target/XCore/AsmPrinter/Makefile
index 82dc1df..f0e883e 100644
--- a/lib/Target/XCore/AsmPrinter/Makefile
+++ b/lib/Target/XCore/AsmPrinter/Makefile
@@ -9,6 +9,7 @@
LEVEL = ../../../..
LIBRARYNAME = LLVMXCoreAsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' XCore target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp b/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp
index 2a561c6..40d7160 100644
--- a/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp
+++ b/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp
@@ -37,7 +37,6 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include <algorithm>
#include <cctype>
@@ -69,11 +68,10 @@ namespace {
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode);
- void emitGlobalDirective(const std::string &name);
- void emitExternDirective(const std::string &name);
+ void emitGlobalDirective(const MCSymbol *Sym);
- void emitArrayBound(const std::string &name, const GlobalVariable *GV);
- virtual void PrintGlobalVariable(const GlobalVariable *GV);
+ void emitArrayBound(const MCSymbol *Sym, const GlobalVariable *GV);
+ virtual void EmitGlobalVariable(const GlobalVariable *GV);
void emitFunctionStart(MachineFunction &MF);
void emitFunctionEnd(MachineFunction &MF);
@@ -95,55 +93,44 @@ namespace {
#include "XCoreGenAsmWriter.inc"
-void XCoreAsmPrinter::
-emitGlobalDirective(const std::string &name)
-{
- O << MAI->getGlobalDirective() << name;
- O << "\n";
-}
-
-void XCoreAsmPrinter::
-emitExternDirective(const std::string &name)
-{
- O << "\t.extern\t" << name;
- O << '\n';
+void XCoreAsmPrinter::emitGlobalDirective(const MCSymbol *Sym) {
+ O << MAI->getGlobalDirective() << *Sym << "\n";
}
-void XCoreAsmPrinter::
-emitArrayBound(const std::string &name, const GlobalVariable *GV)
-{
+void XCoreAsmPrinter::emitArrayBound(const MCSymbol *Sym,
+ const GlobalVariable *GV) {
assert(((GV->hasExternalLinkage() ||
GV->hasWeakLinkage()) ||
GV->hasLinkOnceLinkage()) && "Unexpected linkage");
if (const ArrayType *ATy = dyn_cast<ArrayType>(
- cast<PointerType>(GV->getType())->getElementType()))
- {
- O << MAI->getGlobalDirective() << name << ".globound" << "\n";
- O << MAI->getSetDirective() << name << ".globound" << ","
- << ATy->getNumElements() << "\n";
+ cast<PointerType>(GV->getType())->getElementType())) {
+ O << MAI->getGlobalDirective() << *Sym;
+ O << ".globound" << "\n";
+ O << MAI->getSetDirective() << *Sym;
+ O << ".globound" << "," << ATy->getNumElements() << "\n";
if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) {
// TODO Use COMDAT groups for LinkOnceLinkage
- O << MAI->getWeakDefDirective() << name << ".globound" << "\n";
+ O << MAI->getWeakDefDirective() << *Sym << ".globound" << "\n";
}
}
}
-void XCoreAsmPrinter::PrintGlobalVariable(const GlobalVariable *GV) {
+void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
// Check to see if this is a special global used by LLVM, if so, emit it.
if (!GV->hasInitializer() ||
EmitSpecialLLVMGlobal(GV))
return;
const TargetData *TD = TM.getTargetData();
-
OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GV, Mang,TM));
+
- std::string name = Mang->getMangledName(GV);
+ MCSymbol *GVSym = GetGlobalValueSymbol(GV);
Constant *C = GV->getInitializer();
unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType());
// Mark the start of the global
- O << "\t.cc_top " << name << ".data," << name << "\n";
+ O << "\t.cc_top " << *GVSym << ".data," << *GVSym << "\n";
switch (GV->getLinkage()) {
case GlobalValue::AppendingLinkage:
@@ -153,12 +140,11 @@ void XCoreAsmPrinter::PrintGlobalVariable(const GlobalVariable *GV) {
case GlobalValue::WeakAnyLinkage:
case GlobalValue::WeakODRLinkage:
case GlobalValue::ExternalLinkage:
- emitArrayBound(name, GV);
- emitGlobalDirective(name);
+ emitArrayBound(GVSym, GV);
+ emitGlobalDirective(GVSym);
// TODO Use COMDAT groups for LinkOnceLinkage
- if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) {
- O << MAI->getWeakDefDirective() << name << "\n";
- }
+ if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())
+ O << MAI->getWeakDefDirective() << *GVSym << "\n";
// FALL THROUGH
case GlobalValue::InternalLinkage:
case GlobalValue::PrivateLinkage:
@@ -181,25 +167,23 @@ void XCoreAsmPrinter::PrintGlobalVariable(const GlobalVariable *GV) {
Size *= MaxThreads;
}
if (MAI->hasDotTypeDotSizeDirective()) {
- O << "\t.type " << name << ",@object\n";
- O << "\t.size " << name << "," << Size << "\n";
+ O << "\t.type " << *GVSym << ",@object\n";
+ O << "\t.size " << *GVSym << "," << Size << "\n";
}
- O << name << ":\n";
+ O << *GVSym << ":\n";
EmitGlobalConstant(C);
if (GV->isThreadLocal()) {
- for (unsigned i = 1; i < MaxThreads; ++i) {
+ for (unsigned i = 1; i < MaxThreads; ++i)
EmitGlobalConstant(C);
- }
- }
- if (Size < 4) {
- // The ABI requires that unsigned scalar types smaller than 32 bits
- // are are padded to 32 bits.
- EmitZeros(4 - Size);
}
+ // The ABI requires that unsigned scalar types smaller than 32 bits
+ // are padded to 32 bits.
+ if (Size < 4)
+ OutStreamer.EmitZeros(4 - Size, 0);
// Mark the end of the global
- O << "\t.cc_bottom " << name << ".data\n";
+ O << "\t.cc_bottom " << *GVSym << ".data\n";
}
/// Emit the directives on the start of functions
@@ -210,7 +194,7 @@ void XCoreAsmPrinter::emitFunctionStart(MachineFunction &MF) {
OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
// Mark the start of the function
- O << "\t.cc_top " << CurrentFnName << ".function," << CurrentFnName << "\n";
+ O << "\t.cc_top " << *CurrentFnSym << ".function," << *CurrentFnSym << "\n";
switch (F->getLinkage()) {
default: llvm_unreachable("Unknown linkage type!");
@@ -219,31 +203,29 @@ void XCoreAsmPrinter::emitFunctionStart(MachineFunction &MF) {
case Function::LinkerPrivateLinkage:
break;
case Function::ExternalLinkage:
- emitGlobalDirective(CurrentFnName);
+ emitGlobalDirective(CurrentFnSym);
break;
case Function::LinkOnceAnyLinkage:
case Function::LinkOnceODRLinkage:
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
// TODO Use COMDAT groups for LinkOnceLinkage
- O << MAI->getGlobalDirective() << CurrentFnName << "\n";
- O << MAI->getWeakDefDirective() << CurrentFnName << "\n";
+ O << MAI->getGlobalDirective() << *CurrentFnSym << "\n";
+ O << MAI->getWeakDefDirective() << *CurrentFnSym << "\n";
break;
}
// (1 << 1) byte aligned
EmitAlignment(MF.getAlignment(), F, 1);
- if (MAI->hasDotTypeDotSizeDirective()) {
- O << "\t.type " << CurrentFnName << ",@function\n";
- }
- O << CurrentFnName << ":\n";
+ if (MAI->hasDotTypeDotSizeDirective())
+ O << "\t.type " << *CurrentFnSym << ",@function\n";
+
+ O << *CurrentFnSym << ":\n";
}
/// Emit the directives on the end of functions
-void XCoreAsmPrinter::
-emitFunctionEnd(MachineFunction &MF)
-{
+void XCoreAsmPrinter::emitFunctionEnd(MachineFunction &MF) {
// Mark the end of the function
- O << "\t.cc_bottom " << CurrentFnName << ".function\n";
+ O << "\t.cc_bottom " << *CurrentFnSym << ".function\n";
}
/// runOnMachineFunction - This uses the printMachineInstruction()
@@ -318,10 +300,10 @@ void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
O << MO.getImm();
break;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
break;
case MachineOperand::MO_GlobalAddress:
- O << Mang->getMangledName(MO.getGlobal());
+ O << *GetGlobalValueSymbol(MO.getGlobal());
break;
case MachineOperand::MO_ExternalSymbol:
O << MO.getSymbolName();
@@ -333,8 +315,9 @@ void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
<< '_' << MO.getIndex();
+ break;
case MachineOperand::MO_BlockAddress:
- GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);
+ O << *GetBlockAddressSymbol(MO.getBlockAddress());
break;
default:
llvm_unreachable("not implemented");
diff --git a/lib/Target/XCore/Makefile b/lib/Target/XCore/Makefile
index bd3b52a..3bb127f 100644
--- a/lib/Target/XCore/Makefile
+++ b/lib/Target/XCore/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMXCoreCodeGen
TARGET = XCore
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = XCoreGenRegisterInfo.h.inc XCoreGenRegisterNames.inc \
diff --git a/lib/Target/XCore/TargetInfo/Makefile b/lib/Target/XCore/TargetInfo/Makefile
index 07473d2..83bba13 100644
--- a/lib/Target/XCore/TargetInfo/Makefile
+++ b/lib/Target/XCore/TargetInfo/Makefile
@@ -6,8 +6,10 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../../..
LIBRARYNAME = LLVMXCoreInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Transforms/Hello/Makefile b/lib/Transforms/Hello/Makefile
index c5e75d4..46f8098 100644
--- a/lib/Transforms/Hello/Makefile
+++ b/lib/Transforms/Hello/Makefile
@@ -11,6 +11,7 @@ LEVEL = ../../..
LIBRARYNAME = LLVMHello
LOADABLE_MODULE = 1
USEDLIBS =
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Transforms/IPO/Inliner.cpp b/lib/Transforms/IPO/Inliner.cpp
index 5725db1..0990278 100644
--- a/lib/Transforms/IPO/Inliner.cpp
+++ b/lib/Transforms/IPO/Inliner.cpp
@@ -171,7 +171,16 @@ static bool InlineCallIfPossible(CallSite CS, CallGraph &CG,
return true;
}
-
+
+unsigned Inliner::getInlineThreshold(Function* Caller) const {
+ if (Caller && !Caller->isDeclaration() &&
+ Caller->hasFnAttr(Attribute::OptimizeForSize) &&
+ InlineLimit.getNumOccurrences() == 0)
+ return 50;
+ else
+ return InlineThreshold;
+}
+
/// shouldInline - Return true if the inliner should attempt to inline
/// at the given CallSite.
bool Inliner::shouldInline(CallSite CS) {
@@ -190,14 +199,8 @@ bool Inliner::shouldInline(CallSite CS) {
}
int Cost = IC.getValue();
- int CurrentThreshold = InlineThreshold;
Function *Caller = CS.getCaller();
- if (Caller && !Caller->isDeclaration() &&
- Caller->hasFnAttr(Attribute::OptimizeForSize) &&
- InlineLimit.getNumOccurrences() == 0 &&
- InlineThreshold != 50)
- CurrentThreshold = 50;
-
+ int CurrentThreshold = getInlineThreshold(Caller);
float FudgeFactor = getInlineFudgeFactor(CS);
if (Cost >= (int)(CurrentThreshold * FudgeFactor)) {
DEBUG(dbgs() << " NOT Inlining: cost=" << Cost
@@ -233,13 +236,8 @@ bool Inliner::shouldInline(CallSite CS) {
outerCallsFound = true;
int Cost2 = IC2.getValue();
- int CurrentThreshold2 = InlineThreshold;
Function *Caller2 = CS2.getCaller();
- if (Caller2 && !Caller2->isDeclaration() &&
- Caller2->hasFnAttr(Attribute::OptimizeForSize) &&
- InlineThreshold != 50)
- CurrentThreshold2 = 50;
-
+ int CurrentThreshold2 = getInlineThreshold(Caller2);
float FudgeFactor2 = getInlineFudgeFactor(CS2);
if (Cost2 >= (int)(CurrentThreshold2 * FudgeFactor2))
diff --git a/lib/Transforms/IPO/Makefile b/lib/Transforms/IPO/Makefile
index 5c42374..fd018c4 100644
--- a/lib/Transforms/IPO/Makefile
+++ b/lib/Transforms/IPO/Makefile
@@ -10,6 +10,7 @@
LEVEL = ../../..
LIBRARYNAME = LLVMipo
BUILD_ARCHIVE = 1
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Transforms/IPO/StripSymbols.cpp b/lib/Transforms/IPO/StripSymbols.cpp
index ae88d9e..0e0d83a 100644
--- a/lib/Transforms/IPO/StripSymbols.cpp
+++ b/lib/Transforms/IPO/StripSymbols.cpp
@@ -147,7 +147,7 @@ static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) {
// Strip the symbol table of its names.
static void StripTypeSymtab(TypeSymbolTable &ST, bool PreserveDbgInfo) {
for (TypeSymbolTable::iterator TI = ST.begin(), E = ST.end(); TI != E; ) {
- if (PreserveDbgInfo && strncmp(TI->first.c_str(), "llvm.dbg", 8) == 0)
+ if (PreserveDbgInfo && StringRef(TI->first).startswith("llvm.dbg"))
++TI;
else
ST.remove(TI++);
diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index af300fc..fa7bb12 100644
--- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1751,6 +1751,11 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
return BinaryOperator::CreateOr(NotX, NotY);
return BinaryOperator::CreateAnd(NotX, NotY);
}
+
+ } else if (Op0I->getOpcode() == Instruction::AShr) {
+ // ~(~X >>s Y) --> (X >>s Y)
+ if (Value *Op0NotVal = dyn_castNotVal(Op0I->getOperand(0)))
+ return BinaryOperator::CreateAShr(Op0NotVal, Op0I->getOperand(1));
}
}
}
diff --git a/lib/Transforms/InstCombine/InstCombineCasts.cpp b/lib/Transforms/InstCombine/InstCombineCasts.cpp
index e018b35..f25dd35 100644
--- a/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -955,6 +955,19 @@ Instruction *InstCombiner::visitSExt(SExtInst &CI) {
ShAmt);
}
+ // If this input is a trunc from our destination, then turn sext(trunc(x))
+ // into shifts.
+ if (TruncInst *TI = dyn_cast<TruncInst>(Src))
+ if (TI->hasOneUse() && TI->getOperand(0)->getType() == DestTy) {
+ uint32_t SrcBitSize = SrcTy->getScalarSizeInBits();
+ uint32_t DestBitSize = DestTy->getScalarSizeInBits();
+
+ // We need to emit a shl + ashr to do the sign extend.
+ Value *ShAmt = ConstantInt::get(DestTy, DestBitSize-SrcBitSize);
+ Value *Res = Builder->CreateShl(TI->getOperand(0), ShAmt, "sext");
+ return BinaryOperator::CreateAShr(Res, ShAmt);
+ }
+
// If the input is a shl/ashr pair of a same constant, then this is a sign
// extension from a smaller value. If we could trust arbitrary bitwidth
// integers, we could turn this into a truncate to the smaller bit and then
diff --git a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
index 6c0ecc9..ae728dd 100644
--- a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -366,7 +366,7 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
// alloca dead.
// If the RHS is an alloca with a two uses, the other one being a
// llvm.dbg.declare, zapify the store and the declare, making the
- // alloca dead. We must do this to prevent declare's from affecting
+ // alloca dead. We must do this to prevent declares from affecting
// codegen.
if (!SI.isVolatile()) {
if (Ptr->hasOneUse()) {
@@ -408,8 +408,6 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
--BBI;
// Don't count debug info directives, lest they affect codegen,
// and we skip pointer-to-pointer bitcasts, which are NOPs.
- // It is necessary for correctness to skip those that feed into a
- // llvm.dbg.declare, as these are not present when debugging is off.
if (isa<DbgInfoIntrinsic>(BBI) ||
(isa<BitCastInst>(BBI) && isa<PointerType>(BBI->getType()))) {
ScanInsts++;
@@ -475,9 +473,8 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
// If this store is the last instruction in the basic block (possibly
- // excepting debug info instructions and the pointer bitcasts that feed
- // into them), and if the block ends with an unconditional branch, try
- // to move it to the successor block.
+ // excepting debug info instructions), and if the block ends with an
+ // unconditional branch, try to move it to the successor block.
BBI = &SI;
do {
++BBI;
diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 6afc0cd..2e26a75 100644
--- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -407,7 +407,7 @@ Instruction *InstCombiner::visitUDiv(BinaryOperator &I) {
return Common;
if (ConstantInt *C = dyn_cast<ConstantInt>(Op1)) {
- // X udiv C^2 -> X >> C
+ // X udiv 2^C -> X >> C
// Check to see if this is an unsigned division with an exact power of 2,
// if so, convert to a right shift.
if (C->getValue().isPowerOf2()) // 0 not included in isPowerOf2
diff --git a/lib/Transforms/InstCombine/InstCombineShifts.cpp b/lib/Transforms/InstCombine/InstCombineShifts.cpp
index fe91da1..321c91d 100644
--- a/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -404,12 +404,26 @@ Instruction *InstCombiner::visitAShr(BinaryOperator &I) {
if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
// If the input is a SHL by the same constant (ashr (shl X, C), C), then we
- // have a sign-extend idiom. If the input value is known to already be sign
- // extended enough, delete the extension.
+ // have a sign-extend idiom.
Value *X;
- if (match(Op0, m_Shl(m_Value(X), m_Specific(Op1))) &&
- ComputeNumSignBits(X) > Op1C->getZExtValue())
- return ReplaceInstUsesWith(I, X);
+ if (match(Op0, m_Shl(m_Value(X), m_Specific(Op1)))) {
+ // If the input value is known to already be sign extended enough, delete
+ // the extension.
+ if (ComputeNumSignBits(X) > Op1C->getZExtValue())
+ return ReplaceInstUsesWith(I, X);
+
+ // If the input is an extension from the shifted amount value, e.g.
+ // %x = zext i8 %A to i32
+ // %y = shl i32 %x, 24
+ // %z = ashr %y, 24
+ // then turn this into "z = sext i8 A to i32".
+ if (ZExtInst *ZI = dyn_cast<ZExtInst>(X)) {
+ uint32_t SrcBits = ZI->getOperand(0)->getType()->getScalarSizeInBits();
+ uint32_t DestBits = ZI->getType()->getScalarSizeInBits();
+ if (Op1C->getZExtValue() == DestBits-SrcBits)
+ return new SExtInst(ZI->getOperand(0), ZI->getType());
+ }
+ }
}
// See if we can turn a signed shr into an unsigned shr.
diff --git a/lib/Transforms/InstCombine/Makefile b/lib/Transforms/InstCombine/Makefile
index 0c488e78..f9de42a 100644
--- a/lib/Transforms/InstCombine/Makefile
+++ b/lib/Transforms/InstCombine/Makefile
@@ -10,6 +10,7 @@
LEVEL = ../../..
LIBRARYNAME = LLVMInstCombine
BUILD_ARCHIVE = 1
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Transforms/Instrumentation/Makefile b/lib/Transforms/Instrumentation/Makefile
index 6cbc7a9..1238896 100644
--- a/lib/Transforms/Instrumentation/Makefile
+++ b/lib/Transforms/Instrumentation/Makefile
@@ -10,6 +10,7 @@
LEVEL = ../../..
LIBRARYNAME = LLVMInstrumentation
BUILD_ARCHIVE = 1
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Transforms/Instrumentation/OptimalEdgeProfiling.cpp b/lib/Transforms/Instrumentation/OptimalEdgeProfiling.cpp
index 94b0671..5650150 100644
--- a/lib/Transforms/Instrumentation/OptimalEdgeProfiling.cpp
+++ b/lib/Transforms/Instrumentation/OptimalEdgeProfiling.cpp
@@ -130,7 +130,7 @@ bool OptimalEdgeProfiler::runOnModule(Module &M) {
// actual MST is returned but the edges _not_ in the MST.
ProfileInfo::EdgeWeights ECs =
- getAnalysisID<ProfileInfo>(ProfileEstimatorPassID, *F).getEdgeWeights(F);
+ getAnalysis<ProfileInfo>(*F).getEdgeWeights(F);
std::vector<ProfileInfo::EdgeWeight> EdgeVector(ECs.begin(), ECs.end());
MaximumSpanningTree<BasicBlock> MST (EdgeVector);
std::stable_sort(MST.begin(),MST.end());
diff --git a/lib/Transforms/Scalar/CodeGenPrepare.cpp b/lib/Transforms/Scalar/CodeGenPrepare.cpp
index 9c1b440..c3139a5 100644
--- a/lib/Transforms/Scalar/CodeGenPrepare.cpp
+++ b/lib/Transforms/Scalar/CodeGenPrepare.cpp
@@ -617,7 +617,23 @@ bool CodeGenPrepare::OptimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
TLI->getTargetData()->getIntPtrType(AccessTy->getContext());
Value *Result = 0;
- // Start with the scale value.
+
+ // Start with the base register. Do this first so that subsequent address
+ // matching finds it last, which will prevent it from trying to match it
+ // as the scaled value in case it happens to be a mul. That would be
+ // problematic if we've sunk a different mul for the scale, because then
+ // we'd end up sinking both muls.
+ if (AddrMode.BaseReg) {
+ Value *V = AddrMode.BaseReg;
+ if (isa<PointerType>(V->getType()))
+ V = new PtrToIntInst(V, IntPtrTy, "sunkaddr", InsertPt);
+ if (V->getType() != IntPtrTy)
+ V = CastInst::CreateIntegerCast(V, IntPtrTy, /*isSigned=*/true,
+ "sunkaddr", InsertPt);
+ Result = V;
+ }
+
+ // Add the scale value.
if (AddrMode.Scale) {
Value *V = AddrMode.ScaledReg;
if (V->getType() == IntPtrTy) {
@@ -634,17 +650,6 @@ bool CodeGenPrepare::OptimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
V = BinaryOperator::CreateMul(V, ConstantInt::get(IntPtrTy,
AddrMode.Scale),
"sunkaddr", InsertPt);
- Result = V;
- }
-
- // Add in the base register.
- if (AddrMode.BaseReg) {
- Value *V = AddrMode.BaseReg;
- if (isa<PointerType>(V->getType()))
- V = new PtrToIntInst(V, IntPtrTy, "sunkaddr", InsertPt);
- if (V->getType() != IntPtrTy)
- V = CastInst::CreateIntegerCast(V, IntPtrTy, /*isSigned=*/true,
- "sunkaddr", InsertPt);
if (Result)
Result = BinaryOperator::CreateAdd(Result, V, "sunkaddr", InsertPt);
else
diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp
index ac0d850..b29fe74 100644
--- a/lib/Transforms/Scalar/GVN.cpp
+++ b/lib/Transforms/Scalar/GVN.cpp
@@ -70,18 +70,44 @@ static cl::opt<bool> EnableLoadPRE("enable-load-pre", cl::init(true));
/// two values.
namespace {
struct Expression {
- enum ExpressionOpcode { ADD, FADD, SUB, FSUB, MUL, FMUL,
- UDIV, SDIV, FDIV, UREM, SREM,
- FREM, SHL, LSHR, ASHR, AND, OR, XOR, ICMPEQ,
- ICMPNE, ICMPUGT, ICMPUGE, ICMPULT, ICMPULE,
- ICMPSGT, ICMPSGE, ICMPSLT, ICMPSLE, FCMPOEQ,
- FCMPOGT, FCMPOGE, FCMPOLT, FCMPOLE, FCMPONE,
- FCMPORD, FCMPUNO, FCMPUEQ, FCMPUGT, FCMPUGE,
- FCMPULT, FCMPULE, FCMPUNE, EXTRACT, INSERT,
- SHUFFLE, SELECT, TRUNC, ZEXT, SEXT, FPTOUI,
- FPTOSI, UITOFP, SITOFP, FPTRUNC, FPEXT,
- PTRTOINT, INTTOPTR, BITCAST, GEP, CALL, CONSTANT,
- INSERTVALUE, EXTRACTVALUE, EMPTY, TOMBSTONE };
+ enum ExpressionOpcode {
+ ADD = Instruction::Add,
+ FADD = Instruction::FAdd,
+ SUB = Instruction::Sub,
+ FSUB = Instruction::FSub,
+ MUL = Instruction::Mul,
+ FMUL = Instruction::FMul,
+ UDIV = Instruction::UDiv,
+ SDIV = Instruction::SDiv,
+ FDIV = Instruction::FDiv,
+ UREM = Instruction::URem,
+ SREM = Instruction::SRem,
+ FREM = Instruction::FRem,
+ SHL = Instruction::Shl,
+ LSHR = Instruction::LShr,
+ ASHR = Instruction::AShr,
+ AND = Instruction::And,
+ OR = Instruction::Or,
+ XOR = Instruction::Xor,
+ TRUNC = Instruction::Trunc,
+ ZEXT = Instruction::ZExt,
+ SEXT = Instruction::SExt,
+ FPTOUI = Instruction::FPToUI,
+ FPTOSI = Instruction::FPToSI,
+ UITOFP = Instruction::UIToFP,
+ SITOFP = Instruction::SIToFP,
+ FPTRUNC = Instruction::FPTrunc,
+ FPEXT = Instruction::FPExt,
+ PTRTOINT = Instruction::PtrToInt,
+ INTTOPTR = Instruction::IntToPtr,
+ BITCAST = Instruction::BitCast,
+ ICMPEQ, ICMPNE, ICMPUGT, ICMPUGE, ICMPULT, ICMPULE,
+ ICMPSGT, ICMPSGE, ICMPSLT, ICMPSLE, FCMPOEQ,
+ FCMPOGT, FCMPOGE, FCMPOLT, FCMPOLE, FCMPONE,
+ FCMPORD, FCMPUNO, FCMPUEQ, FCMPUGT, FCMPUGE,
+ FCMPULT, FCMPULE, FCMPUNE, EXTRACT, INSERT,
+ SHUFFLE, SELECT, GEP, CALL, CONSTANT,
+ INSERTVALUE, EXTRACTVALUE, EMPTY, TOMBSTONE };
ExpressionOpcode opcode;
const Type* type;
@@ -127,9 +153,7 @@ namespace {
uint32_t nextValueNumber;
- Expression::ExpressionOpcode getOpcode(BinaryOperator* BO);
Expression::ExpressionOpcode getOpcode(CmpInst* C);
- Expression::ExpressionOpcode getOpcode(CastInst* C);
Expression create_expression(BinaryOperator* BO);
Expression create_expression(CmpInst* C);
Expression create_expression(ShuffleVectorInst* V);
@@ -200,30 +224,6 @@ struct isPodLike<Expression> { static const bool value = true; };
//===----------------------------------------------------------------------===//
// ValueTable Internal Functions
//===----------------------------------------------------------------------===//
-Expression::ExpressionOpcode ValueTable::getOpcode(BinaryOperator* BO) {
- switch(BO->getOpcode()) {
- default: // THIS SHOULD NEVER HAPPEN
- llvm_unreachable("Binary operator with unknown opcode?");
- case Instruction::Add: return Expression::ADD;
- case Instruction::FAdd: return Expression::FADD;
- case Instruction::Sub: return Expression::SUB;
- case Instruction::FSub: return Expression::FSUB;
- case Instruction::Mul: return Expression::MUL;
- case Instruction::FMul: return Expression::FMUL;
- case Instruction::UDiv: return Expression::UDIV;
- case Instruction::SDiv: return Expression::SDIV;
- case Instruction::FDiv: return Expression::FDIV;
- case Instruction::URem: return Expression::UREM;
- case Instruction::SRem: return Expression::SREM;
- case Instruction::FRem: return Expression::FREM;
- case Instruction::Shl: return Expression::SHL;
- case Instruction::LShr: return Expression::LSHR;
- case Instruction::AShr: return Expression::ASHR;
- case Instruction::And: return Expression::AND;
- case Instruction::Or: return Expression::OR;
- case Instruction::Xor: return Expression::XOR;
- }
-}
Expression::ExpressionOpcode ValueTable::getOpcode(CmpInst* C) {
if (isa<ICmpInst>(C)) {
@@ -263,25 +263,6 @@ Expression::ExpressionOpcode ValueTable::getOpcode(CmpInst* C) {
}
}
-Expression::ExpressionOpcode ValueTable::getOpcode(CastInst* C) {
- switch(C->getOpcode()) {
- default: // THIS SHOULD NEVER HAPPEN
- llvm_unreachable("Cast operator with unknown opcode?");
- case Instruction::Trunc: return Expression::TRUNC;
- case Instruction::ZExt: return Expression::ZEXT;
- case Instruction::SExt: return Expression::SEXT;
- case Instruction::FPToUI: return Expression::FPTOUI;
- case Instruction::FPToSI: return Expression::FPTOSI;
- case Instruction::UIToFP: return Expression::UITOFP;
- case Instruction::SIToFP: return Expression::SITOFP;
- case Instruction::FPTrunc: return Expression::FPTRUNC;
- case Instruction::FPExt: return Expression::FPEXT;
- case Instruction::PtrToInt: return Expression::PTRTOINT;
- case Instruction::IntToPtr: return Expression::INTTOPTR;
- case Instruction::BitCast: return Expression::BITCAST;
- }
-}
-
Expression ValueTable::create_expression(CallInst* C) {
Expression e;
@@ -302,7 +283,7 @@ Expression ValueTable::create_expression(BinaryOperator* BO) {
e.varargs.push_back(lookup_or_add(BO->getOperand(1)));
e.function = 0;
e.type = BO->getType();
- e.opcode = getOpcode(BO);
+ e.opcode = static_cast<Expression::ExpressionOpcode>(BO->getOpcode());
return e;
}
@@ -325,7 +306,7 @@ Expression ValueTable::create_expression(CastInst* C) {
e.varargs.push_back(lookup_or_add(C->getOperand(0)));
e.function = 0;
e.type = C->getType();
- e.opcode = getOpcode(C);
+ e.opcode = static_cast<Expression::ExpressionOpcode>(C->getOpcode());
return e;
}
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp
index ce1307c..17f7d98 100644
--- a/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -471,6 +471,13 @@ void IndVarSimplify::RewriteIVExpressions(Loop *L, const Type *LargestType,
// Compute the final addrec to expand into code.
const SCEV *AR = IU->getReplacementExpr(*UI);
+ // Evaluate the expression out of the loop, if possible.
+ if (!L->contains(UI->getUser())) {
+ const SCEV *ExitVal = SE->getSCEVAtScope(AR, L->getParentLoop());
+ if (ExitVal->isLoopInvariant(L))
+ AR = ExitVal;
+ }
+
// FIXME: It is an extremely bad idea to indvar substitute anything more
// complex than affine induction variables. Doing so will put expensive
// polynomial evaluations inside of the loop, and the str reduction pass
@@ -522,11 +529,10 @@ void IndVarSimplify::RewriteIVExpressions(Loop *L, const Type *LargestType,
Rewriter.clear();
// Now that we're done iterating through lists, clean up any instructions
// which are now dead.
- while (!DeadInsts.empty()) {
- Instruction *Inst = dyn_cast_or_null<Instruction>(DeadInsts.pop_back_val());
- if (Inst)
+ while (!DeadInsts.empty())
+ if (Instruction *Inst =
+ dyn_cast_or_null<Instruction>(DeadInsts.pop_back_val()))
RecursivelyDeleteTriviallyDeadInstructions(Inst);
- }
}
/// If there's a single exit block, sink any loop-invariant values that
diff --git a/lib/Transforms/Scalar/Makefile b/lib/Transforms/Scalar/Makefile
index cc42fd0..e18f30f 100644
--- a/lib/Transforms/Scalar/Makefile
+++ b/lib/Transforms/Scalar/Makefile
@@ -10,6 +10,7 @@
LEVEL = ../../..
LIBRARYNAME = LLVMScalarOpts
BUILD_ARCHIVE = 1
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
index 9e1e79a..f473480 100644
--- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp
+++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp
@@ -85,10 +85,6 @@ namespace {
/// isUnsafe - This is set to true if the alloca cannot be SROA'd.
bool isUnsafe : 1;
- /// needsCleanup - This is set to true if there is some use of the alloca
- /// that requires cleanup.
- bool needsCleanup : 1;
-
/// isMemCpySrc - This is true if this aggregate is memcpy'd from.
bool isMemCpySrc : 1;
@@ -96,15 +92,14 @@ namespace {
bool isMemCpyDst : 1;
AllocaInfo()
- : isUnsafe(false), needsCleanup(false),
- isMemCpySrc(false), isMemCpyDst(false) {}
+ : isUnsafe(false), isMemCpySrc(false), isMemCpyDst(false) {}
};
unsigned SRThreshold;
void MarkUnsafe(AllocaInfo &I) { I.isUnsafe = true; }
- int isSafeAllocaToScalarRepl(AllocaInst *AI);
+ bool isSafeAllocaToScalarRepl(AllocaInst *AI);
void isSafeForScalarRepl(Instruction *I, AllocaInst *AI, uint64_t Offset,
AllocaInfo &Info);
@@ -119,7 +114,6 @@ namespace {
void DoScalarReplacement(AllocaInst *AI,
std::vector<AllocaInst*> &WorkList);
void DeleteDeadInstructions();
- void CleanupAllocaUsers(Value *V);
AllocaInst *AddNewAlloca(Function &F, const Type *Ty, AllocaInst *Base);
void RewriteForScalarRepl(Instruction *I, AllocaInst *AI, uint64_t Offset,
@@ -281,14 +275,7 @@ bool SROA::performScalarRepl(Function &F) {
getNumSAElements(AI->getAllocatedType()) <= SRThreshold/4) {
// Check that all of the users of the allocation are capable of being
// transformed.
- switch (isSafeAllocaToScalarRepl(AI)) {
- default: llvm_unreachable("Unexpected value!");
- case 0: // Not safe to scalar replace.
- break;
- case 1: // Safe, but requires cleanup/canonicalizations first
- CleanupAllocaUsers(AI);
- // FALL THROUGH.
- case 3: // Safe to scalar replace.
+ if (isSafeAllocaToScalarRepl(AI)) {
DoScalarReplacement(AI, WorkList);
Changed = true;
continue;
@@ -437,14 +424,6 @@ void SROA::isSafeForScalarRepl(Instruction *I, AllocaInst *AI, uint64_t Offset,
SIType, true, Info);
} else
MarkUnsafe(Info);
- } else if (isa<DbgInfoIntrinsic>(UI)) {
- // If one user is DbgInfoIntrinsic then check if all users are
- // DbgInfoIntrinsics.
- if (OnlyUsedByDbgInfoIntrinsics(I)) {
- Info.needsCleanup = true;
- return;
- }
- MarkUnsafe(Info);
} else {
DEBUG(errs() << " Transformation preventing inst: " << *User << '\n');
MarkUnsafe(Info);
@@ -752,9 +731,16 @@ void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst,
}
break;
}
- // If OtherPtr has already been rewritten, this intrinsic will be dead.
- if (OtherPtr == NewElts[0])
+ // Copying the alloca to itself is a no-op: just delete it.
+ if (OtherPtr == AI || OtherPtr == NewElts[0]) {
+ // This code will run twice for a no-op memcpy -- once for each operand.
+ // Put only one reference to MI on the DeadInsts list.
+ for (SmallVector<Value*, 32>::const_iterator I = DeadInsts.begin(),
+ E = DeadInsts.end(); I != E; ++I)
+ if (*I == MI) return;
+ DeadInsts.push_back(MI);
return;
+ }
if (ConstantExpr *BCE = dyn_cast<ConstantExpr>(OtherPtr))
if (BCE->getOpcode() == Instruction::BitCast)
@@ -779,10 +765,7 @@ void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst,
Value *OtherElt = 0;
unsigned OtherEltAlign = MemAlignment;
- if (OtherPtr == AI) {
- OtherElt = NewElts[i];
- OtherEltAlign = 0;
- } else if (OtherPtr) {
+ if (OtherPtr) {
Value *Idx[2] = { Zero,
ConstantInt::get(Type::getInt32Ty(MI->getContext()), i) };
OtherElt = GetElementPtrInst::CreateInBounds(OtherPtr, Idx, Idx + 2,
@@ -1146,7 +1129,7 @@ static bool HasPadding(const Type *Ty, const TargetData &TD) {
/// isSafeStructAllocaToScalarRepl - Check to see if the specified allocation of
/// an aggregate can be broken down into elements. Return 0 if not, 3 if safe,
/// or 1 if safe after canonicalization has been performed.
-int SROA::isSafeAllocaToScalarRepl(AllocaInst *AI) {
+bool SROA::isSafeAllocaToScalarRepl(AllocaInst *AI) {
// Loop over the use list of the alloca. We can only transform it if all of
// the users are safe to transform.
AllocaInfo Info;
@@ -1154,7 +1137,7 @@ int SROA::isSafeAllocaToScalarRepl(AllocaInst *AI) {
isSafeForScalarRepl(AI, AI, 0, Info);
if (Info.isUnsafe) {
DEBUG(dbgs() << "Cannot transform: " << *AI << '\n');
- return 0;
+ return false;
}
// Okay, we know all the users are promotable. If the aggregate is a memcpy
@@ -1164,29 +1147,9 @@ int SROA::isSafeAllocaToScalarRepl(AllocaInst *AI) {
// struct.
if (Info.isMemCpySrc && Info.isMemCpyDst &&
HasPadding(AI->getAllocatedType(), *TD))
- return 0;
-
- // If we require cleanup, return 1, otherwise return 3.
- return Info.needsCleanup ? 1 : 3;
-}
+ return false;
-/// CleanupAllocaUsers - If SROA reported that it can promote the specified
-/// allocation, but only if cleaned up, perform the cleanups required.
-void SROA::CleanupAllocaUsers(Value *V) {
- for (Value::use_iterator UI = V->use_begin(), E = V->use_end();
- UI != E; ) {
- User *U = *UI++;
- Instruction *I = cast<Instruction>(U);
- SmallVector<DbgInfoIntrinsic *, 2> DbgInUses;
- if (!isa<StoreInst>(I) && OnlyUsedByDbgInfoIntrinsics(I, &DbgInUses)) {
- // Safe to remove debug info uses.
- while (!DbgInUses.empty()) {
- DbgInfoIntrinsic *DI = DbgInUses.pop_back_val();
- DI->eraseFromParent();
- }
- I->eraseFromParent();
- }
- }
+ return true;
}
/// MergeInType - Add the 'In' type to the accumulated type (Accum) so far at
@@ -1321,10 +1284,6 @@ bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial, const Type *&VecTy,
}
}
- // Ignore dbg intrinsic.
- if (isa<DbgInfoIntrinsic>(User))
- continue;
-
// Otherwise, we cannot handle this!
return false;
}
@@ -1449,18 +1408,11 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset) {
} else {
// Noop transfer. Src == Dst
}
-
MTI->eraseFromParent();
continue;
}
- // If user is a dbg info intrinsic then it is safe to remove it.
- if (isa<DbgInfoIntrinsic>(User)) {
- User->eraseFromParent();
- continue;
- }
-
llvm_unreachable("Unsupported operation!");
}
}
diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
index 9183f3a..a49da9c 100644
--- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp
+++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
@@ -81,6 +81,10 @@ public:
/// and the return value has 'i8*' type.
Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B);
+ /// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
+ /// specified pointer arguments.
+ Value *EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B);
+
/// EmitMemCpy - Emit a call to the memcpy function to the builder. This
/// always expects that the size has type 'intptr_t' and Dst/Src are pointers.
Value *EmitMemCpy(Value *Dst, Value *Src, Value *Len,
@@ -176,6 +180,22 @@ Value *LibCallOptimization::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B) {
return CI;
}
+/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
+/// specified pointer arguments.
+Value *LibCallOptimization::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B) {
+ Module *M = Caller->getParent();
+ AttributeWithIndex AWI[2];
+ AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
+ AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
+ const Type *I8Ptr = Type::getInt8PtrTy(*Context);
+ Value *StrCpy = M->getOrInsertFunction("strcpy", AttrListPtr::get(AWI, 2),
+ I8Ptr, I8Ptr, I8Ptr, NULL);
+ CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
+ "strcpy");
+ if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
+ CI->setCallingConv(F->getCallingConv());
+ return CI;
+}
/// EmitMemCpy - Emit a call to the memcpy function to the builder. This always
/// expects that the size has type 'intptr_t' and Dst/Src are pointers.
@@ -1181,6 +1201,31 @@ struct MemMoveChkOpt : public LibCallOptimization {
}
};
+struct StrCpyChkOpt : public LibCallOptimization {
+ virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
+ // These optimizations require TargetData.
+ if (!TD) return 0;
+
+ const FunctionType *FT = Callee->getFunctionType();
+ if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
+ !isa<PointerType>(FT->getParamType(0)) ||
+ !isa<PointerType>(FT->getParamType(1)) ||
+ !isa<IntegerType>(FT->getParamType(2)))
+ return 0;
+
+ ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(3));
+ if (!SizeCI)
+ return 0;
+
+ // We don't have any length information, just lower to a plain strcpy.
+ if (SizeCI->isAllOnesValue())
+ return EmitStrCpy(CI->getOperand(1), CI->getOperand(2), B);
+
+ return 0;
+ }
+};
+
+
//===----------------------------------------------------------------------===//
// Math Library Optimizations
//===----------------------------------------------------------------------===//
@@ -1725,6 +1770,7 @@ namespace {
// Object Size Checking
MemCpyChkOpt MemCpyChk; MemSetChkOpt MemSetChk; MemMoveChkOpt MemMoveChk;
+ StrCpyChkOpt StrCpyChk;
bool Modified; // This is only used by doInitialization.
public:
@@ -1836,6 +1882,7 @@ void SimplifyLibCalls::InitOptimizations() {
Optimizations["__memcpy_chk"] = &MemCpyChk;
Optimizations["__memset_chk"] = &MemSetChk;
Optimizations["__memmove_chk"] = &MemMoveChk;
+ Optimizations["__strcpy_chk"] = &StrCpyChk;
}
diff --git a/lib/Transforms/Utils/BasicBlockUtils.cpp b/lib/Transforms/Utils/BasicBlockUtils.cpp
index e902688..7bc4fcd 100644
--- a/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -615,11 +615,6 @@ Value *llvm::FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB,
Instruction *Inst = --ScanFrom;
if (isa<DbgInfoIntrinsic>(Inst))
continue;
- // We skip pointer-to-pointer bitcasts, which are NOPs.
- // It is necessary for correctness to skip those that feed into a
- // llvm.dbg.declare, as these are not present when debugging is off.
- if (isa<BitCastInst>(Inst) && isa<PointerType>(Inst->getType()))
- continue;
// Restore ScanFrom to expected value in case next test succeeds
ScanFrom++;
diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp
index 90e929e..92bdf2d 100644
--- a/lib/Transforms/Utils/Local.cpp
+++ b/lib/Transforms/Utils/Local.cpp
@@ -609,30 +609,6 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB) {
return true;
}
-
-
-/// OnlyUsedByDbgIntrinsics - Return true if the instruction I is only used
-/// by DbgIntrinsics. If DbgInUses is specified then the vector is filled
-/// with the DbgInfoIntrinsic that use the instruction I.
-bool llvm::OnlyUsedByDbgInfoIntrinsics(Instruction *I,
- SmallVectorImpl<DbgInfoIntrinsic *> *DbgInUses) {
- if (DbgInUses)
- DbgInUses->clear();
-
- for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); UI != UE;
- ++UI) {
- if (DbgInfoIntrinsic *DI = dyn_cast<DbgInfoIntrinsic>(*UI)) {
- if (DbgInUses)
- DbgInUses->push_back(DI);
- } else {
- if (DbgInUses)
- DbgInUses->clear();
- return false;
- }
- }
- return true;
-}
-
/// EliminateDuplicatePHINodes - Check for and eliminate duplicate PHI
/// nodes in this block. This doesn't try to be clever about PHI nodes
/// which differ only in the order of the incoming values, but instcombine
diff --git a/lib/Transforms/Utils/LoopSimplify.cpp b/lib/Transforms/Utils/LoopSimplify.cpp
index 7fcc5f7..e81b779 100644
--- a/lib/Transforms/Utils/LoopSimplify.cpp
+++ b/lib/Transforms/Utils/LoopSimplify.cpp
@@ -232,7 +232,7 @@ ReprocessLoop:
PN->eraseFromParent();
}
- // If this loop has muliple exits and the exits all go to the same
+ // If this loop has multiple exits and the exits all go to the same
// block, attempt to merge the exits. This helps several passes, such
// as LoopRotation, which do not support loops with multiple exits.
// SimplifyCFG also does this (and this code uses the same utility
diff --git a/lib/Transforms/Utils/Makefile b/lib/Transforms/Utils/Makefile
index d1e9336..b9761df 100644
--- a/lib/Transforms/Utils/Makefile
+++ b/lib/Transforms/Utils/Makefile
@@ -10,6 +10,7 @@
LEVEL = ../../..
LIBRARYNAME = LLVMTransformUtils
BUILD_ARCHIVE = 1
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
index baaa130..d9261ac 100644
--- a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
+++ b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
@@ -23,6 +23,7 @@
#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
+#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/ADT/DenseMap.h"
@@ -76,16 +77,6 @@ bool llvm::isAllocaPromotable(const AllocaInst *AI) {
return false; // Don't allow a store OF the AI, only INTO the AI.
if (SI->isVolatile())
return false;
- } else if (const BitCastInst *BC = dyn_cast<BitCastInst>(*UI)) {
- // A bitcast that does not feed into debug info inhibits promotion.
- if (!BC->hasOneUse() || !isa<DbgInfoIntrinsic>(*BC->use_begin()))
- return false;
- // If the only use is by debug info, this alloca will not exist in
- // non-debug code, so don't try to promote; this ensures the same
- // codegen with debug info. Otherwise, debug info should not
- // inhibit promotion (but we must examine other uses).
- if (AI->hasOneUse())
- return false;
} else {
return false;
}
@@ -173,6 +164,7 @@ namespace {
std::vector<AllocaInst*> Allocas;
DominatorTree &DT;
DominanceFrontier &DF;
+ DIFactory *DIF;
/// AST - An AliasSetTracker object to update. If null, don't update it.
///
@@ -209,7 +201,7 @@ namespace {
public:
PromoteMem2Reg(const std::vector<AllocaInst*> &A, DominatorTree &dt,
DominanceFrontier &df, AliasSetTracker *ast)
- : Allocas(A), DT(dt), DF(df), AST(ast) {}
+ : Allocas(A), DT(dt), DF(df), DIF(0), AST(ast) {}
void run();
@@ -251,8 +243,9 @@ namespace {
LargeBlockInfo &LBI);
void PromoteSingleBlockAlloca(AllocaInst *AI, AllocaInfo &Info,
LargeBlockInfo &LBI);
-
-
+ void ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, StoreInst* SI,
+ uint64_t Offset);
+
void RenamePass(BasicBlock *BB, BasicBlock *Pred,
RenamePassData::ValVector &IncVals,
std::vector<RenamePassData> &Worklist);
@@ -290,15 +283,7 @@ namespace {
for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end();
UI != E;) {
Instruction *User = cast<Instruction>(*UI++);
- if (BitCastInst *BC = dyn_cast<BitCastInst>(User)) {
- // Remove any uses of this alloca in DbgInfoInstrinsics.
- assert(BC->hasOneUse() && "Unexpected alloca uses!");
- DbgInfoIntrinsic *DI = cast<DbgInfoIntrinsic>(*BC->use_begin());
- DI->eraseFromParent();
- BC->eraseFromParent();
- continue;
- }
-
+
if (StoreInst *SI = dyn_cast<StoreInst>(User)) {
// Remember the basic blocks which define new values for the alloca
DefiningBlocks.push_back(SI->getParent());
@@ -324,6 +309,19 @@ namespace {
} // end of anonymous namespace
+/// Finds the llvm.dbg.declare intrinsic corresponding to an alloca if any.
+static DbgDeclareInst *findDbgDeclare(AllocaInst *AI) {
+ Function *F = AI->getParent()->getParent();
+ for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
+ for (BasicBlock::iterator BI = (*FI).begin(), BE = (*FI).end();
+ BI != BE; ++BI)
+ if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI))
+ if (DDI->getAddress() == AI)
+ return DDI;
+
+ return 0;
+}
+
void PromoteMem2Reg::run() {
Function &F = *DF.getRoot()->getParent();
@@ -362,6 +360,8 @@ void PromoteMem2Reg::run() {
// Finally, after the scan, check to see if the store is all that is left.
if (Info.UsingBlocks.empty()) {
+ // Record debuginfo for the store before removing it.
+ ConvertDebugDeclareToDebugValue(findDbgDeclare(AI), Info.OnlyStore, 0);
// Remove the (now dead) store and alloca.
Info.OnlyStore->eraseFromParent();
LBI.deleteValue(Info.OnlyStore);
@@ -388,8 +388,11 @@ void PromoteMem2Reg::run() {
if (Info.UsingBlocks.empty()) {
// Remove the (now dead) stores and alloca.
+ DbgDeclareInst *DDI = findDbgDeclare(AI);
while (!AI->use_empty()) {
StoreInst *SI = cast<StoreInst>(AI->use_back());
+ // Record debuginfo for the store before removing it.
+ ConvertDebugDeclareToDebugValue(DDI, SI, 0);
SI->eraseFromParent();
LBI.deleteValue(SI);
}
@@ -851,6 +854,18 @@ void PromoteMem2Reg::PromoteSingleBlockAlloca(AllocaInst *AI, AllocaInfo &Info,
}
}
+// Inserts a llvm.dbg.value instrinsic before the stores to an alloca'd value
+// that has an associated llvm.dbg.decl intrinsic.
+void PromoteMem2Reg::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
+ StoreInst* SI,
+ uint64_t Offset) {
+ if (!DDI) return;
+
+ if (!DIF)
+ DIF = new DIFactory(*SI->getParent()->getParent()->getParent());
+ DIF->InsertDbgValueIntrinsic(SI->getOperand(0), Offset,
+ DIVariable(DDI->getVariable()), SI);
+}
// QueuePhiNode - queues a phi-node to be added to a basic-block for a specific
// Alloca returns true if there wasn't already a phi-node for that variable
@@ -964,6 +979,8 @@ NextIteration:
// what value were we writing?
IncomingVals[ai->second] = SI->getOperand(0);
+ // Record debuginfo for the store before removing it.
+ ConvertDebugDeclareToDebugValue(findDbgDeclare(Dest), SI, 0);
BB->getInstList().erase(SI);
}
}
diff --git a/lib/Transforms/Utils/ValueMapper.cpp b/lib/Transforms/Utils/ValueMapper.cpp
index 39331d7..a6e6701 100644
--- a/lib/Transforms/Utils/ValueMapper.cpp
+++ b/lib/Transforms/Utils/ValueMapper.cpp
@@ -13,12 +13,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/ValueMapper.h"
-#include "llvm/DerivedTypes.h" // For getNullValue(Type::Int32Ty)
+#include "llvm/Type.h"
#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/Metadata.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
Value *llvm::MapValue(const Value *V, ValueMapTy &VM) {
@@ -28,11 +27,19 @@ Value *llvm::MapValue(const Value *V, ValueMapTy &VM) {
// NOTE: VMSlot can be invalidated by any reference to VM, which can grow the
// DenseMap. This includes any recursive calls to MapValue.
- // Global values and metadata do not need to be seeded into the ValueMap if
- // they are using the identity mapping.
- if (isa<GlobalValue>(V) || isa<InlineAsm>(V) || isa<MetadataBase>(V))
+ // Global values and non-function-local metadata do not need to be seeded into
+ // the ValueMap if they are using the identity mapping.
+ if (isa<GlobalValue>(V) || isa<InlineAsm>(V) || isa<MDString>(V) ||
+ (isa<MDNode>(V) && !cast<MDNode>(V)->isFunctionLocal()))
return VMSlot = const_cast<Value*>(V);
+ if (const MDNode *MD = dyn_cast<MDNode>(V)) {
+ SmallVector<Value*, 4> Elts;
+ for (unsigned i = 0; i != MD->getNumOperands(); i++)
+ Elts.push_back(MD->getOperand(i) ? MapValue(MD->getOperand(i), VM) : 0);
+ return VM[V] = MDNode::get(V->getContext(), Elts.data(), Elts.size());
+ }
+
Constant *C = const_cast<Constant*>(dyn_cast<Constant>(V));
if (C == 0) return 0;
@@ -111,14 +118,10 @@ Value *llvm::MapValue(const Value *V, ValueMapTy &VM) {
return VM[V] = C;
}
- if (BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
- Function *F = cast<Function>(MapValue(BA->getFunction(), VM));
- BasicBlock *BB = cast_or_null<BasicBlock>(MapValue(BA->getBasicBlock(),VM));
- return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock());
- }
-
- llvm_unreachable("Unknown type of constant!");
- return 0;
+ BlockAddress *BA = cast<BlockAddress>(C);
+ Function *F = cast<Function>(MapValue(BA->getFunction(), VM));
+ BasicBlock *BB = cast_or_null<BasicBlock>(MapValue(BA->getBasicBlock(),VM));
+ return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock());
}
/// RemapInstruction - Convert the instruction operands from referencing the
@@ -131,3 +134,4 @@ void llvm::RemapInstruction(Instruction *I, ValueMapTy &ValueMap) {
*op = V;
}
}
+
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index eff2c77..c9f3849 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -2062,9 +2062,9 @@ void Value::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const {
else
W.printAlias(cast<GlobalAlias>(GV));
} else if (const MDNode *N = dyn_cast<MDNode>(this)) {
- Function *F = N->getFunction();
+ const Function *F = N->getFunction();
SlotTracker SlotTable(F);
- AssemblyWriter W(OS, SlotTable, getModuleFromVal(F), AAW);
+ AssemblyWriter W(OS, SlotTable, F ? getModuleFromVal(F) : 0, AAW);
W.printMDNodeBody(N);
} else if (const NamedMDNode *N = dyn_cast<NamedMDNode>(this)) {
SlotTracker SlotTable(N->getParent());
diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp
index a371c6f..65155f1 100644
--- a/lib/VMCore/Attributes.cpp
+++ b/lib/VMCore/Attributes.cpp
@@ -56,8 +56,6 @@ std::string Attribute::getAsString(Attributes Attrs) {
Result += "optsize ";
if (Attrs & Attribute::NoInline)
Result += "noinline ";
- if (Attrs & Attribute::InlineHint)
- Result += "inlinehint ";
if (Attrs & Attribute::AlwaysInline)
Result += "alwaysinline ";
if (Attrs & Attribute::StackProtect)
diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp
index 2161841..5e4c9fb 100644
--- a/lib/VMCore/AutoUpgrade.cpp
+++ b/lib/VMCore/AutoUpgrade.cpp
@@ -521,7 +521,7 @@ void llvm::CheckDebugInfoIntrinsics(Module *M) {
if (Function *Declare = M->getFunction("llvm.dbg.declare")) {
if (!Declare->use_empty()) {
DbgDeclareInst *DDI = cast<DbgDeclareInst>(Declare->use_back());
- if (!isa<MDNode>(DDI->getOperand(2))) {
+ if (!isa<MDNode>(DDI->getOperand(1)) ||!isa<MDNode>(DDI->getOperand(2))) {
while (!Declare->use_empty()) {
CallInst *CI = cast<CallInst>(Declare->use_back());
CI->eraseFromParent();
diff --git a/lib/VMCore/CMakeLists.txt b/lib/VMCore/CMakeLists.txt
index 61d01ee..5ecedf1 100644
--- a/lib/VMCore/CMakeLists.txt
+++ b/lib/VMCore/CMakeLists.txt
@@ -16,7 +16,6 @@ add_llvm_library(LLVMCore
IRBuilder.cpp
LLVMContext.cpp
LeakDetector.cpp
- Mangler.cpp
Metadata.cpp
Module.cpp
ModuleProvider.cpp
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index 3a24389..ddd5587 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -1673,14 +1673,15 @@ Constant *llvm::ConstantFoldCompareInstruction(LLVMContext &Context,
SmallVector<Constant*, 16> C1Elts, C2Elts;
C1->getVectorElements(Context, C1Elts);
C2->getVectorElements(Context, C2Elts);
+ if (C1Elts.empty() || C2Elts.empty())
+ return 0;
// If we can constant fold the comparison of each element, constant fold
// the whole vector comparison.
SmallVector<Constant*, 4> ResElts;
for (unsigned i = 0, e = C1Elts.size(); i != e; ++i) {
// Compare the elements, producing an i1 result or constant expr.
- ResElts.push_back(
- ConstantExpr::getCompare(pred, C1Elts[i], C2Elts[i]));
+ ResElts.push_back(ConstantExpr::getCompare(pred, C1Elts[i], C2Elts[i]));
}
return ConstantVector::get(&ResElts[0], ResElts.size());
}
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index cc8961f..916aac6 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -1630,7 +1630,7 @@ Constant *ConstantExpr::getInBoundsGetElementPtr(Constant *C,
}
Constant *
-ConstantExpr::getICmp(unsigned short pred, Constant* LHS, Constant* RHS) {
+ConstantExpr::getICmp(unsigned short pred, Constant *LHS, Constant *RHS) {
assert(LHS->getType() == RHS->getType());
assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE &&
pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid ICmp Predicate");
@@ -1646,13 +1646,16 @@ ConstantExpr::getICmp(unsigned short pred, Constant* LHS, Constant* RHS) {
// Get the key type with both the opcode and predicate
const ExprMapKeyType Key(Instruction::ICmp, ArgVec, pred);
+ const Type *ResultTy = Type::getInt1Ty(LHS->getContext());
+ if (const VectorType *VT = dyn_cast<VectorType>(LHS->getType()))
+ ResultTy = VectorType::get(ResultTy, VT->getNumElements());
+
LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl;
- return
- pImpl->ExprConstants.getOrCreate(Type::getInt1Ty(LHS->getContext()), Key);
+ return pImpl->ExprConstants.getOrCreate(ResultTy, Key);
}
Constant *
-ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
+ConstantExpr::getFCmp(unsigned short pred, Constant *LHS, Constant *RHS) {
assert(LHS->getType() == RHS->getType());
assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && "Invalid FCmp Predicate");
@@ -1666,10 +1669,13 @@ ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
ArgVec.push_back(RHS);
// Get the key type with both the opcode and predicate
const ExprMapKeyType Key(Instruction::FCmp, ArgVec, pred);
-
+
+ const Type *ResultTy = Type::getInt1Ty(LHS->getContext());
+ if (const VectorType *VT = dyn_cast<VectorType>(LHS->getType()))
+ ResultTy = VectorType::get(ResultTy, VT->getNumElements());
+
LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl;
- return
- pImpl->ExprConstants.getOrCreate(Type::getInt1Ty(LHS->getContext()), Key);
+ return pImpl->ExprConstants.getOrCreate(ResultTy, Key);
}
Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val,
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 2619047..e2b920e 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -2079,25 +2079,26 @@ unsigned CastInst::isEliminableCastPair(
return secondOp;
case 3:
// no-op cast in second op implies firstOp as long as the DestTy
- // is integer
- if (DstTy->isInteger())
+ // is integer and we are not converting between a vector and a
+ // non vector type.
+ if (!isa<VectorType>(SrcTy) && DstTy->isInteger())
return firstOp;
return 0;
case 4:
// no-op cast in second op implies firstOp as long as the DestTy
- // is floating point
+ // is floating point.
if (DstTy->isFloatingPoint())
return firstOp;
return 0;
case 5:
// no-op cast in first op implies secondOp as long as the SrcTy
- // is an integer
+ // is an integer.
if (SrcTy->isInteger())
return secondOp;
return 0;
case 6:
// no-op cast in first op implies secondOp as long as the SrcTy
- // is a floating point
+ // is a floating point.
if (SrcTy->isFloatingPoint())
return secondOp;
return 0;
@@ -2714,6 +2715,8 @@ BitCastInst::BitCastInst(
// CmpInst Classes
//===----------------------------------------------------------------------===//
+void CmpInst::Anchor() const {}
+
CmpInst::CmpInst(const Type *ty, OtherOps op, unsigned short predicate,
Value *LHS, Value *RHS, const Twine &Name,
Instruction *InsertBefore)
diff --git a/lib/VMCore/IntrinsicInst.cpp b/lib/VMCore/IntrinsicInst.cpp
index cb9252e..d8f015a 100644
--- a/lib/VMCore/IntrinsicInst.cpp
+++ b/lib/VMCore/IntrinsicInst.cpp
@@ -51,6 +51,17 @@ Value *DbgInfoIntrinsic::StripCast(Value *C) {
}
//===----------------------------------------------------------------------===//
+/// DbgDeclareInst - This represents the llvm.dbg.declare instruction.
+///
+
+Value *DbgDeclareInst::getAddress() const {
+ if (MDNode* MD = cast_or_null<MDNode>(getOperand(1)))
+ return MD->getOperand(0);
+ else
+ return NULL;
+}
+
+//===----------------------------------------------------------------------===//
/// DbgValueInst - This represents the llvm.dbg.value instruction.
///
diff --git a/lib/VMCore/Makefile b/lib/VMCore/Makefile
index e9d3dc8..ecadaee 100644
--- a/lib/VMCore/Makefile
+++ b/lib/VMCore/Makefile
@@ -9,6 +9,7 @@
LEVEL = ../..
LIBRARYNAME = LLVMCore
BUILD_ARCHIVE = 1
+#CXXFLAGS = -fno-rtti
BUILT_SOURCES = $(PROJ_OBJ_ROOT)/include/llvm/Intrinsics.gen
diff --git a/lib/VMCore/Mangler.cpp b/lib/VMCore/Mangler.cpp
deleted file mode 100644
index 7d9f330..0000000
--- a/lib/VMCore/Mangler.cpp
+++ /dev/null
@@ -1,273 +0,0 @@
-//===-- Mangler.cpp - Self-contained c/asm llvm name mangler --------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Unified name mangler for CWriter and assembly backends.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/Mangler.h"
-#include "llvm/Function.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace llvm;
-
-static char HexDigit(int V) {
- return V < 10 ? V+'0' : V+'A'-10;
-}
-
-static void MangleLetter(SmallVectorImpl<char> &OutName, unsigned char C) {
- OutName.push_back('_');
- OutName.push_back(HexDigit(C >> 4));
- OutName.push_back(HexDigit(C & 15));
- OutName.push_back('_');
-}
-
-/// makeNameProper - We don't want identifier names non-C-identifier characters
-/// in them, so mangle them as appropriate.
-///
-/// FIXME: This is deprecated, new code should use getNameWithPrefix and use
-/// MCSymbol printing to handle quotes or not etc.
-///
-void Mangler::makeNameProper(SmallVectorImpl<char> &OutName,
- const Twine &TheName,
- ManglerPrefixTy PrefixTy) {
- SmallString<256> TmpData;
- StringRef X = TheName.toStringRef(TmpData);
- assert(!X.empty() && "Cannot mangle empty strings");
-
- if (!UseQuotes) {
- // If X does not start with (char)1, add the prefix.
- StringRef::iterator I = X.begin();
- if (*I == 1) {
- ++I; // Skip over the no-prefix marker.
- } else {
- if (PrefixTy == Mangler::Private)
- OutName.append(PrivatePrefix, PrivatePrefix+strlen(PrivatePrefix));
- else if (PrefixTy == Mangler::LinkerPrivate)
- OutName.append(LinkerPrivatePrefix,
- LinkerPrivatePrefix+strlen(LinkerPrivatePrefix));
- OutName.append(Prefix, Prefix+strlen(Prefix));
- }
-
- // Mangle the first letter specially, don't allow numbers unless the target
- // explicitly allows them.
- if (!SymbolsCanStartWithDigit && *I >= '0' && *I <= '9')
- MangleLetter(OutName, *I++);
-
- for (StringRef::iterator E = X.end(); I != E; ++I) {
- if (!isCharAcceptable(*I))
- MangleLetter(OutName, *I);
- else
- OutName.push_back(*I);
- }
- return;
- }
-
- bool NeedPrefix = true;
- bool NeedQuotes = false;
- StringRef::iterator I = X.begin();
- if (*I == 1) {
- NeedPrefix = false;
- ++I; // Skip over the marker.
- }
-
- // If the first character is a number, we need quotes.
- if (*I >= '0' && *I <= '9')
- NeedQuotes = true;
-
- // Do an initial scan of the string, checking to see if we need quotes or
- // to escape a '"' or not.
- if (!NeedQuotes)
- for (StringRef::iterator E = X.end(); I != E; ++I)
- if (!isCharAcceptable(*I)) {
- NeedQuotes = true;
- break;
- }
-
- // In the common case, we don't need quotes. Handle this quickly.
- if (!NeedQuotes) {
- if (!NeedPrefix) {
- OutName.append(X.begin()+1, X.end()); // Strip off the \001.
- return;
- }
-
- if (PrefixTy == Mangler::Private)
- OutName.append(PrivatePrefix, PrivatePrefix+strlen(PrivatePrefix));
- else if (PrefixTy == Mangler::LinkerPrivate)
- OutName.append(LinkerPrivatePrefix,
- LinkerPrivatePrefix+strlen(LinkerPrivatePrefix));
-
- if (Prefix[0] == 0)
- ; // Common noop, no prefix.
- else if (Prefix[1] == 0)
- OutName.push_back(Prefix[0]); // Common, one character prefix.
- else
- OutName.append(Prefix, Prefix+strlen(Prefix)); // Arbitrary prefix.
- OutName.append(X.begin(), X.end());
- return;
- }
-
- // Add leading quote.
- OutName.push_back('"');
-
- // Add prefixes unless disabled.
- if (NeedPrefix) {
- if (PrefixTy == Mangler::Private)
- OutName.append(PrivatePrefix, PrivatePrefix+strlen(PrivatePrefix));
- else if (PrefixTy == Mangler::LinkerPrivate)
- OutName.append(LinkerPrivatePrefix,
- LinkerPrivatePrefix+strlen(LinkerPrivatePrefix));
- OutName.append(Prefix, Prefix+strlen(Prefix));
- }
-
- // Add the piece that we already scanned through.
- OutName.append(X.begin()+!NeedPrefix, I);
-
- // Otherwise, construct the string the expensive way.
- for (StringRef::iterator E = X.end(); I != E; ++I) {
- if (*I == '"') {
- const char *Quote = "_QQ_";
- OutName.append(Quote, Quote+4);
- } else if (*I == '\n') {
- const char *Newline = "_NL_";
- OutName.append(Newline, Newline+4);
- } else
- OutName.push_back(*I);
- }
-
- // Add trailing quote.
- OutName.push_back('"');
-}
-
-/// getMangledName - Returns the mangled name of V, an LLVM Value,
-/// in the current module. If 'Suffix' is specified, the name ends with the
-/// specified suffix. If 'ForcePrivate' is specified, the label is specified
-/// to have a private label prefix.
-///
-/// FIXME: This is deprecated, new code should use getNameWithPrefix and use
-/// MCSymbol printing to handle quotes or not etc.
-///
-std::string Mangler::getMangledName(const GlobalValue *GV, const char *Suffix,
- bool ForcePrivate) {
- assert((!isa<Function>(GV) || !cast<Function>(GV)->isIntrinsic()) &&
- "Intrinsic functions cannot be mangled by Mangler");
-
- ManglerPrefixTy PrefixTy =
- (GV->hasPrivateLinkage() || ForcePrivate) ? Mangler::Private :
- GV->hasLinkerPrivateLinkage() ? Mangler::LinkerPrivate : Mangler::Default;
-
- SmallString<128> Result;
- if (GV->hasName()) {
- makeNameProper(Result, GV->getNameStr() + Suffix, PrefixTy);
- return Result.str().str();
- }
-
- // Get the ID for the global, assigning a new one if we haven't got one
- // already.
- unsigned &ID = AnonGlobalIDs[GV];
- if (ID == 0) ID = NextAnonGlobalID++;
-
- // Must mangle the global into a unique ID.
- makeNameProper(Result, "__unnamed_" + utostr(ID) + Suffix, PrefixTy);
- return Result.str().str();
-}
-
-/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
-/// and the specified name as the global variable name. GVName must not be
-/// empty.
-void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
- const Twine &GVName, ManglerPrefixTy PrefixTy) {
- SmallString<256> TmpData;
- StringRef Name = GVName.toStringRef(TmpData);
- assert(!Name.empty() && "getNameWithPrefix requires non-empty name");
-
- // If the global name is not led with \1, add the appropriate prefixes.
- if (Name[0] != '\1') {
- if (PrefixTy == Mangler::Private)
- OutName.append(PrivatePrefix, PrivatePrefix+strlen(PrivatePrefix));
- else if (PrefixTy == Mangler::LinkerPrivate)
- OutName.append(LinkerPrivatePrefix,
- LinkerPrivatePrefix+strlen(LinkerPrivatePrefix));
-
- if (Prefix[0] == 0)
- ; // Common noop, no prefix.
- else if (Prefix[1] == 0)
- OutName.push_back(Prefix[0]); // Common, one character prefix.
- else
- OutName.append(Prefix, Prefix+strlen(Prefix)); // Arbitrary prefix.
- } else {
- Name = Name.substr(1);
- }
-
- OutName.append(Name.begin(), Name.end());
-}
-
-
-/// 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 Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
- const GlobalValue *GV,
- bool isImplicitlyPrivate) {
- // If this global has a name, handle it simply.
- if (GV->hasName()) {
- ManglerPrefixTy PrefixTy = Mangler::Default;
- if (GV->hasPrivateLinkage() || isImplicitlyPrivate)
- PrefixTy = Mangler::Private;
- else if (GV->hasLinkerPrivateLinkage())
- PrefixTy = Mangler::LinkerPrivate;
-
- return getNameWithPrefix(OutName, GV->getName(), PrefixTy);
- }
-
- // If the global variable doesn't have a name, return a unique name for the
- // global based on a numbering.
-
- // Anonymous names always get prefixes.
- if (GV->hasPrivateLinkage() || isImplicitlyPrivate)
- OutName.append(PrivatePrefix, PrivatePrefix+strlen(PrivatePrefix));
- else if (GV->hasLinkerPrivateLinkage())
- OutName.append(LinkerPrivatePrefix,
- LinkerPrivatePrefix+strlen(LinkerPrivatePrefix));;
- OutName.append(Prefix, Prefix+strlen(Prefix));
-
- // Get the ID for the global, assigning a new one if we haven't got one
- // already.
- unsigned &ID = AnonGlobalIDs[GV];
- if (ID == 0) ID = NextAnonGlobalID++;
-
- // Must mangle the global into a unique ID.
- raw_svector_ostream(OutName) << "__unnamed_" << ID;
-}
-
-
-Mangler::Mangler(Module &M, const char *prefix, const char *privatePrefix,
- const char *linkerPrivatePrefix)
- : Prefix(prefix), PrivatePrefix(privatePrefix),
- LinkerPrivatePrefix(linkerPrivatePrefix), UseQuotes(false),
- SymbolsCanStartWithDigit(false), NextAnonGlobalID(1) {
- std::fill(AcceptableChars, array_endof(AcceptableChars), 0);
-
- // Letters and numbers are acceptable.
- for (unsigned char X = 'a'; X <= 'z'; ++X)
- markCharAcceptable(X);
- for (unsigned char X = 'A'; X <= 'Z'; ++X)
- markCharAcceptable(X);
- for (unsigned char X = '0'; X <= '9'; ++X)
- markCharAcceptable(X);
-
- // These chars are acceptable.
- markCharAcceptable('_');
- markCharAcceptable('$');
- markCharAcceptable('.');
- markCharAcceptable('@');
-}
diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp
index 7988b44..ee8e713 100644
--- a/lib/VMCore/Metadata.cpp
+++ b/lib/VMCore/Metadata.cpp
@@ -28,7 +28,7 @@ using namespace llvm;
//
MDString::MDString(LLVMContext &C, StringRef S)
- : MetadataBase(Type::getMetadataTy(C), Value::MDStringVal), Str(S) {}
+ : Value(Type::getMetadataTy(C), Value::MDStringVal), Str(S) {}
MDString *MDString::get(LLVMContext &Context, StringRef Str) {
LLVMContextImpl *pImpl = Context.pImpl;
@@ -93,7 +93,7 @@ static MDNodeOperand *getOperandPtr(MDNode *N, unsigned Op) {
MDNode::MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
bool isFunctionLocal)
-: MetadataBase(Type::getMetadataTy(C), Value::MDNodeVal) {
+: Value(Type::getMetadataTy(C), Value::MDNodeVal) {
NumOperands = NumVals;
if (isFunctionLocal)
@@ -121,67 +121,60 @@ MDNode::~MDNode() {
Op->~MDNodeOperand();
}
-#ifndef NDEBUG
-static Function *assertLocalFunction(const MDNode *N,
- SmallPtrSet<const MDNode *, 32> &Visited) {
- Function *F = NULL;
- // Only visit each MDNode once.
- if (!Visited.insert(N)) return F;
-
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
- Value *V = N->getOperand(i);
- Function *NewF = NULL;
- if (!V) continue;
- if (Instruction *I = dyn_cast<Instruction>(V))
- NewF = I->getParent()->getParent();
- else if (BasicBlock *BB = dyn_cast<BasicBlock>(V))
- NewF = BB->getParent();
- else if (Argument *A = dyn_cast<Argument>(V))
- NewF = A->getParent();
- else if (MDNode *MD = dyn_cast<MDNode>(V))
- if (MD->isFunctionLocal())
- NewF = assertLocalFunction(MD, Visited);
- if (F && NewF) assert(F == NewF && "inconsistent function-local metadata");
- if (!F) F = NewF;
- }
- return F;
+static const Function *getFunctionForValue(Value *V) {
+ assert(!isa<MDNode>(V) && "does not iterate over metadata operands");
+ if (!V) return NULL;
+ if (Instruction *I = dyn_cast<Instruction>(V))
+ return I->getParent()->getParent();
+ if (BasicBlock *BB = dyn_cast<BasicBlock>(V))
+ return BB->getParent();
+ if (Argument *A = dyn_cast<Argument>(V))
+ return A->getParent();
+ return NULL;
}
-#endif
-static Function *getFunctionHelper(const MDNode *N,
- SmallPtrSet<const MDNode *, 32> &Visited) {
- assert(N->isFunctionLocal() && "Should only be called on function-local MD");
#ifndef NDEBUG
- return assertLocalFunction(N, Visited);
-#endif
- Function *F = NULL;
- // Only visit each MDNode once.
- if (!Visited.insert(N)) return F;
-
+static const Function *assertLocalFunction(const MDNode *N) {
+ if (!N->isFunctionLocal()) return 0;
+
+ const Function *F = 0, *NewF = 0;
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
- Value *V = N->getOperand(i);
- if (!V) continue;
- if (Instruction *I = dyn_cast<Instruction>(V))
- F = I->getParent()->getParent();
- else if (BasicBlock *BB = dyn_cast<BasicBlock>(V))
- F = BB->getParent();
- else if (Argument *A = dyn_cast<Argument>(V))
- F = A->getParent();
- else if (MDNode *MD = dyn_cast<MDNode>(V))
- if (MD->isFunctionLocal())
- F = getFunctionHelper(MD, Visited);
- if (F) break;
+ if (Value *V = N->getOperand(i)) {
+ if (MDNode *MD = dyn_cast<MDNode>(V))
+ NewF = assertLocalFunction(MD);
+ else
+ NewF = getFunctionForValue(V);
+ }
+ if (F == 0)
+ F = NewF;
+ else
+ assert((NewF == 0 || F == NewF) &&"inconsistent function-local metadata");
}
return F;
}
+#endif
// getFunction - If this metadata is function-local and recursively has a
// function-local operand, return the first such operand's parent function.
-// Otherwise, return null.
-Function *MDNode::getFunction() const {
+// Otherwise, return null. getFunction() should not be used for performance-
+// critical code because it recursively visits all the MDNode's operands.
+const Function *MDNode::getFunction() const {
+#ifndef NDEBUG
+ return assertLocalFunction(this);
+#endif
if (!isFunctionLocal()) return NULL;
- SmallPtrSet<const MDNode *, 32> Visited;
- return getFunctionHelper(this, Visited);
+
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
+ if (Value *V = getOperand(i)) {
+ if (MDNode *MD = dyn_cast<MDNode>(V)) {
+ if (const Function *F = MD->getFunction())
+ return F;
+ } else {
+ return getFunctionForValue(V);
+ }
+ }
+ }
+ return NULL;
}
// destroy - Delete this node. Only when there are no uses.
diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp
index 39da8fb..45000f2 100644
--- a/lib/VMCore/Pass.cpp
+++ b/lib/VMCore/Pass.cpp
@@ -21,6 +21,7 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/PassNameParser.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Atomic.h"
#include "llvm/System/Mutex.h"
@@ -394,6 +395,8 @@ void PassRegistrationListener::enumeratePasses() {
getPassRegistrar()->EnumerateWith(this);
}
+PassNameParser::~PassNameParser() {}
+
//===----------------------------------------------------------------------===//
// AnalysisUsage Class Implementation
//
diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp
index b37b2ae..0c0d64e 100644
--- a/lib/VMCore/PassManager.cpp
+++ b/lib/VMCore/PassManager.cpp
@@ -127,6 +127,9 @@ public:
bool doFinalization(Module &M);
bool doFinalization(Function &F);
+ virtual PMDataManager *getAsPMDataManager() { return this; }
+ virtual Pass *getAsPass() { return this; }
+
virtual const char *getPassName() const {
return "BasicBlock Pass Manager";
}
@@ -169,7 +172,7 @@ private:
public:
static char ID;
explicit FunctionPassManagerImpl(int Depth) :
- Pass(&ID), PMDataManager(Depth),
+ Pass(PT_PassManager, &ID), PMDataManager(Depth),
PMTopLevelManager(TLM_Function), wasRun(false) { }
/// add - Add a pass to the queue of passes to run. This passes ownership of
@@ -196,15 +199,17 @@ public:
///
bool doFinalization(Module &M);
+
+ virtual PMDataManager *getAsPMDataManager() { return this; }
+ virtual Pass *getAsPass() { return this; }
+
/// Pass Manager itself does not invalidate any analysis info.
void getAnalysisUsage(AnalysisUsage &Info) const {
Info.setPreservesAll();
}
inline void addTopLevelPass(Pass *P) {
-
- if (ImmutablePass *IP = dynamic_cast<ImmutablePass *> (P)) {
-
+ if (ImmutablePass *IP = P->getAsImmutablePass()) {
// P is a immutable pass and it will be managed by this
// top level manager. Set up analysis resolver to connect them.
AnalysisResolver *AR = new AnalysisResolver(*this);
@@ -236,7 +241,7 @@ class MPPassManager : public Pass, public PMDataManager {
public:
static char ID;
explicit MPPassManager(int Depth) :
- Pass(&ID), PMDataManager(Depth) { }
+ Pass(PT_PassManager, &ID), PMDataManager(Depth) { }
// Delete on the fly managers.
virtual ~MPPassManager() {
@@ -271,6 +276,9 @@ public:
return "Module Pass Manager";
}
+ virtual PMDataManager *getAsPMDataManager() { return this; }
+ virtual Pass *getAsPass() { return this; }
+
// Print passes managed by this manager
void dumpPassStructure(unsigned Offset) {
llvm::dbgs() << std::string(Offset*2, ' ') << "ModulePass Manager\n";
@@ -313,7 +321,8 @@ class PassManagerImpl : public Pass,
public:
static char ID;
explicit PassManagerImpl(int Depth) :
- Pass(&ID), PMDataManager(Depth), PMTopLevelManager(TLM_Pass) { }
+ Pass(PT_PassManager, &ID), PMDataManager(Depth),
+ PMTopLevelManager(TLM_Pass) { }
/// add - Add a pass to the queue of passes to run. This passes ownership of
/// the Pass to the PassManager. When the PassManager is destroyed, the pass
@@ -333,8 +342,7 @@ public:
}
inline void addTopLevelPass(Pass *P) {
- if (ImmutablePass *IP = dynamic_cast<ImmutablePass *> (P)) {
-
+ if (ImmutablePass *IP = P->getAsImmutablePass()) {
// P is a immutable pass and it will be managed by this
// top level manager. Set up analysis resolver to connect them.
AnalysisResolver *AR = new AnalysisResolver(*this);
@@ -347,6 +355,9 @@ public:
}
}
+ virtual PMDataManager *getAsPMDataManager() { return this; }
+ virtual Pass *getAsPass() { return this; }
+
MPPassManager *getContainedManager(unsigned N) {
assert(N < PassManagers.size() && "Pass number out of range!");
MPPassManager *MP = static_cast<MPPassManager *>(PassManagers[N]);
@@ -390,7 +401,7 @@ public:
/// passStarted - This method creates a timer for the given pass if it doesn't
/// already have one, and starts the timer.
Timer *passStarted(Pass *P) {
- if (dynamic_cast<PMDataManager *>(P))
+ if (P->getAsPMDataManager())
return 0;
sys::SmartScopedLock<true> Lock(*TimingInfoMutex);
@@ -584,11 +595,11 @@ void PMTopLevelManager::dumpPasses() const {
// Every class that derives from PMDataManager also derives from Pass
// (sometimes indirectly), but there's no inheritance relationship
- // between PMDataManager and Pass, so we have to dynamic_cast to get
+ // between PMDataManager and Pass, so we have to getAsPass to get
// from a PMDataManager* to a Pass*.
for (SmallVector<PMDataManager *, 8>::const_iterator I = PassManagers.begin(),
E = PassManagers.end(); I != E; ++I)
- dynamic_cast<Pass *>(*I)->dumpPassStructure(1);
+ (*I)->getAsPass()->dumpPassStructure(1);
}
void PMTopLevelManager::dumpArguments() const {
@@ -670,7 +681,7 @@ bool PMDataManager::preserveHigherLevelAnalysis(Pass *P) {
for (SmallVector<Pass *, 8>::iterator I = HigherLevelAnalysis.begin(),
E = HigherLevelAnalysis.end(); I != E; ++I) {
Pass *P1 = *I;
- if (!dynamic_cast<ImmutablePass*>(P1) &&
+ if (P1->getAsImmutablePass() == 0 &&
std::find(PreservedSet.begin(), PreservedSet.end(),
P1->getPassInfo()) ==
PreservedSet.end())
@@ -713,8 +724,8 @@ void PMDataManager::removeNotPreservedAnalysis(Pass *P) {
for (std::map<AnalysisID, Pass*>::iterator I = AvailableAnalysis.begin(),
E = AvailableAnalysis.end(); I != E; ) {
std::map<AnalysisID, Pass*>::iterator Info = I++;
- if (!dynamic_cast<ImmutablePass*>(Info->second)
- && std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) ==
+ if (Info->second->getAsImmutablePass() == 0 &&
+ std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) ==
PreservedSet.end()) {
// Remove this analysis
if (PassDebugging >= Details) {
@@ -737,7 +748,7 @@ void PMDataManager::removeNotPreservedAnalysis(Pass *P) {
I = InheritedAnalysis[Index]->begin(),
E = InheritedAnalysis[Index]->end(); I != E; ) {
std::map<AnalysisID, Pass *>::iterator Info = I++;
- if (!dynamic_cast<ImmutablePass*>(Info->second) &&
+ if (Info->second->getAsImmutablePass() == 0 &&
std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) ==
PreservedSet.end()) {
// Remove this analysis
@@ -854,12 +865,12 @@ void PMDataManager::add(Pass *P, bool ProcessAnalysis) {
// Set P as P's last user until someone starts using P.
// However, if P is a Pass Manager then it does not need
// to record its last user.
- if (!dynamic_cast<PMDataManager *>(P))
+ if (P->getAsPMDataManager() == 0)
LastUses.push_back(P);
TPM->setLastUser(LastUses, P);
if (!TransferLastUses.empty()) {
- Pass *My_PM = dynamic_cast<Pass *>(this);
+ Pass *My_PM = getAsPass();
TPM->setLastUser(TransferLastUses, My_PM);
TransferLastUses.clear();
}
@@ -968,7 +979,7 @@ void PMDataManager::dumpLastUses(Pass *P, unsigned Offset) const{
void PMDataManager::dumpPassArguments() const {
for (SmallVector<Pass *, 8>::const_iterator I = PassVector.begin(),
E = PassVector.end(); I != E; ++I) {
- if (PMDataManager *PMD = dynamic_cast<PMDataManager *>(*I))
+ if (PMDataManager *PMD = (*I)->getAsPMDataManager())
PMD->dumpPassArguments();
else
if (const PassInfo *PI = (*I)->getPassInfo())
@@ -1469,7 +1480,7 @@ Pass* MPPassManager::getOnTheFlyPass(Pass *MP, const PassInfo *PI, Function &F){
FPP->releaseMemoryOnTheFly();
FPP->run(F);
- return (dynamic_cast<PMTopLevelManager *>(FPP))->findAnalysisPass(PI);
+ return ((PMTopLevelManager*)FPP)->findAnalysisPass(PI);
}
@@ -1586,7 +1597,7 @@ void PMStack::push(PMDataManager *PM) {
void PMStack::dump() {
for (std::deque<PMDataManager *>::iterator I = S.begin(),
E = S.end(); I != E; ++I)
- printf("%s ", dynamic_cast<Pass *>(*I)->getPassName());
+ printf("%s ", (*I)->getAsPass()->getPassName());
if (!S.empty())
printf("\n");
@@ -1616,16 +1627,18 @@ void FunctionPass::assignPassManager(PMStack &PMS,
PassManagerType PreferredType) {
// Find Module Pass Manager
- while(!PMS.empty()) {
+ while (!PMS.empty()) {
if (PMS.top()->getPassManagerType() > PMT_FunctionPassManager)
PMS.pop();
else
break;
}
- FPPassManager *FPP = dynamic_cast<FPPassManager *>(PMS.top());
- // Create new Function Pass Manager
- if (!FPP) {
+ // Create new Function Pass Manager if needed.
+ FPPassManager *FPP;
+ if (PMS.top()->getPassManagerType() == PMT_FunctionPassManager) {
+ FPP = (FPPassManager *)PMS.top();
+ } else {
assert(!PMS.empty() && "Unable to create Function Pass Manager");
PMDataManager *PMD = PMS.top();
@@ -1653,17 +1666,16 @@ void FunctionPass::assignPassManager(PMStack &PMS,
/// in the PM Stack and add self into that manager.
void BasicBlockPass::assignPassManager(PMStack &PMS,
PassManagerType PreferredType) {
- BBPassManager *BBP = NULL;
+ BBPassManager *BBP;
// Basic Pass Manager is a leaf pass manager. It does not handle
// any other pass manager.
- if (!PMS.empty())
- BBP = dynamic_cast<BBPassManager *>(PMS.top());
-
- // If leaf manager is not Basic Block Pass manager then create new
- // basic Block Pass manager.
-
- if (!BBP) {
+ if (!PMS.empty() &&
+ PMS.top()->getPassManagerType() == PMT_BasicBlockPassManager) {
+ BBP = (BBPassManager *)PMS.top();
+ } else {
+ // If leaf manager is not Basic Block Pass manager then create new
+ // basic Block Pass manager.
assert(!PMS.empty() && "Unable to create BasicBlock Pass Manager");
PMDataManager *PMD = PMS.top();
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index ec475e4..76d9d43 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -1301,6 +1301,8 @@ void Verifier::visitAllocaInst(AllocaInst &AI) {
&AI);
Assert1(PTy->getElementType()->isSized(), "Cannot allocate unsized type",
&AI);
+ Assert1(AI.getArraySize()->getType()->isInteger(32),
+ "Alloca array size must be i32", &AI);
visitInstruction(AI);
}
@@ -1579,7 +1581,7 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
// If the intrinsic takes MDNode arguments, verify that they are either global
// or are local to *this* function.
- for (unsigned i = 0, e = CI.getNumOperands(); i != e; ++i)
+ for (unsigned i = 1, e = CI.getNumOperands(); i != e; ++i)
if (MDNode *MD = dyn_cast<MDNode>(CI.getOperand(i))) {
if (!MD->isFunctionLocal()) continue;
SmallPtrSet<MDNode *, 32> Visited;
@@ -1589,12 +1591,17 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
switch (ID) {
default:
break;
- case Intrinsic::dbg_declare: // llvm.dbg.declare
- if (MDNode *MD = dyn_cast<MDNode>(CI.getOperand(1)))
+ case Intrinsic::dbg_declare: { // llvm.dbg.declare
+ Assert1(CI.getOperand(1) && isa<MDNode>(CI.getOperand(1)),
+ "invalid llvm.dbg.declare intrinsic call 1", &CI);
+ MDNode *MD = cast<MDNode>(CI.getOperand(1));
+ Assert1(MD->getNumOperands() == 1,
+ "invalid llvm.dbg.declare intrinsic call 2", &CI);
+ if (MD->getOperand(0))
if (Constant *C = dyn_cast<Constant>(MD->getOperand(0)))
Assert1(C && !isa<ConstantPointerNull>(C),
- "invalid llvm.dbg.declare intrinsic call", &CI);
- break;
+ "invalid llvm.dbg.declare intrinsic call 3", &CI);
+ } break;
case Intrinsic::memcpy:
case Intrinsic::memmove:
case Intrinsic::memset:
diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt
index 78e12fd..1a286db 100644
--- a/projects/CMakeLists.txt
+++ b/projects/CMakeLists.txt
@@ -4,6 +4,8 @@
file(GLOB entries *)
foreach(entry ${entries})
if(IS_DIRECTORY ${entry} AND EXISTS ${entry}/CMakeLists.txt)
- add_subdirectory(${entry})
+ if(NOT (${entry} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/compiler-rt))
+ add_subdirectory(${entry})
+ endif()
endif()
endforeach(entry)
diff --git a/projects/Makefile b/projects/Makefile
index b966fc7..491d596 100644
--- a/projects/Makefile
+++ b/projects/Makefile
@@ -14,6 +14,9 @@ include $(LEVEL)/Makefile.config
# Before 2008.06.24 it lived in llvm-test, so exclude that as well for now.
DIRS:= $(filter-out llvm-test test-suite,$(patsubst $(PROJ_SRC_DIR)/%/Makefile,%,$(wildcard $(PROJ_SRC_DIR)/*/Makefile)))
+# Don't build compiler-rt either, it isn't designed to be built directly.
+DIRS := $(filter-out compiler-rt,$(DIRS))
+
# Sparc cannot link shared libraries (libtool problem?)
ifeq ($(ARCH), Sparc)
DIRS := $(filter-out sample, $(DIRS))
diff --git a/test/Analysis/PostDominators/pr6047_a.ll b/test/Analysis/PostDominators/pr6047_a.ll
new file mode 100644
index 0000000..ec1455b
--- /dev/null
+++ b/test/Analysis/PostDominators/pr6047_a.ll
@@ -0,0 +1,15 @@
+; RUN: opt < %s -postdomtree -analyze | FileCheck %s
+define internal void @f() {
+entry:
+ br i1 undef, label %bb35, label %bb3.i
+
+bb3.i:
+ br label %bb3.i
+
+bb35.loopexit3:
+ br label %bb35
+
+bb35:
+ ret void
+}
+; CHECK: [3] %entry
diff --git a/test/Analysis/PostDominators/pr6047_b.ll b/test/Analysis/PostDominators/pr6047_b.ll
new file mode 100644
index 0000000..7bd2c86
--- /dev/null
+++ b/test/Analysis/PostDominators/pr6047_b.ll
@@ -0,0 +1,19 @@
+; RUN: opt < %s -postdomtree -analyze | FileCheck %s
+define internal void @f() {
+entry:
+ br i1 undef, label %a, label %bb3.i
+
+a:
+ br i1 undef, label %bb35, label %bb3.i
+
+bb3.i:
+ br label %bb3.i
+
+
+bb35.loopexit3:
+ br label %bb35
+
+bb35:
+ ret void
+}
+; CHECK: [4] %entry
diff --git a/test/Analysis/PostDominators/pr6047_c.ll b/test/Analysis/PostDominators/pr6047_c.ll
new file mode 100644
index 0000000..08c9551
--- /dev/null
+++ b/test/Analysis/PostDominators/pr6047_c.ll
@@ -0,0 +1,147 @@
+; RUN: opt < %s -postdomtree -analyze | FileCheck %s
+define internal void @f() {
+entry:
+ br i1 undef, label %bb35, label %bb3.i
+
+bb3.i:
+ br label %bb3.i
+
+bb:
+ br label %bb35
+
+bb.i:
+ br label %bb35
+
+_float32_unpack.exit:
+ br label %bb35
+
+bb.i5:
+ br label %bb35
+
+_float32_unpack.exit8:
+ br label %bb35
+
+bb32.preheader:
+ br label %bb35
+
+bb3:
+ br label %bb35
+
+bb3.split.us:
+ br label %bb35
+
+bb.i4.us:
+ br label %bb35
+
+bb7.i.us:
+ br label %bb35
+
+bb.i4.us.backedge:
+ br label %bb35
+
+bb1.i.us:
+ br label %bb35
+
+bb6.i.us:
+ br label %bb35
+
+bb4.i.us:
+ br label %bb35
+
+bb8.i.us:
+ br label %bb35
+
+bb3.i.loopexit.us:
+ br label %bb35
+
+bb.nph21:
+ br label %bb35
+
+bb4:
+ br label %bb35
+
+bb5:
+ br label %bb35
+
+bb14.preheader:
+ br label %bb35
+
+bb.nph18:
+ br label %bb35
+
+bb8.us.preheader:
+ br label %bb35
+
+bb8.preheader:
+ br label %bb35
+
+bb8.us:
+ br label %bb35
+
+bb8:
+ br label %bb35
+
+bb15.loopexit:
+ br label %bb35
+
+bb15.loopexit2:
+ br label %bb35
+
+bb15:
+ br label %bb35
+
+bb16:
+ br label %bb35
+
+bb17.loopexit.split:
+ br label %bb35
+
+bb.nph14:
+ br label %bb35
+
+bb19:
+ br label %bb35
+
+bb20:
+ br label %bb35
+
+bb29.preheader:
+ br label %bb35
+
+bb.nph:
+ br label %bb35
+
+bb23.us.preheader:
+ br label %bb35
+
+bb23.preheader:
+ br label %bb35
+
+bb23.us:
+ br label %bb35
+
+bb23:
+ br label %bb35
+
+bb30.loopexit:
+ br label %bb35
+
+bb30.loopexit1:
+ br label %bb35
+
+bb30:
+ br label %bb35
+
+bb31:
+ br label %bb35
+
+bb35.loopexit:
+ br label %bb35
+
+bb35.loopexit3:
+ br label %bb35
+
+bb35:
+ ret void
+}
+; CHECK: [3] %entry
diff --git a/test/Analysis/PostDominators/pr6047_d.ll b/test/Analysis/PostDominators/pr6047_d.ll
new file mode 100644
index 0000000..4cfa880
--- /dev/null
+++ b/test/Analysis/PostDominators/pr6047_d.ll
@@ -0,0 +1,24 @@
+; RUN: opt < %s -postdomtree -analyze | FileCheck %s
+define internal void @f() {
+entry:
+ br i1 1, label %a, label %b
+
+a:
+br label %c
+
+b:
+br label %c
+
+c:
+ br i1 undef, label %bb35, label %bb3.i
+
+bb3.i:
+ br label %bb3.i
+
+bb35.loopexit3:
+ br label %bb35
+
+bb35:
+ ret void
+}
+; CHECK: [4] %entry
diff --git a/test/Assembler/functionlocal-metadata.ll b/test/Assembler/functionlocal-metadata.ll
index 8265aa1..16bc9d0 100644
--- a/test/Assembler/functionlocal-metadata.ll
+++ b/test/Assembler/functionlocal-metadata.ll
@@ -9,17 +9,24 @@ entry:
call void @llvm.dbg.declare(metadata !{i32* %1}, metadata !{i32* %1})
; CHECK: metadata !{i32* %1}, metadata !{i32* %1}
call void @llvm.dbg.declare(metadata !{i32 %two}, metadata !{i32 %0})
+; CHECK: metadata !{i32 %two}, metadata !{i32 %0}
call void @llvm.dbg.declare(metadata !{i32 %0}, metadata !{i32* %1, i32 %0})
+; CHECK: metadata !{i32 %0}, metadata !{i32* %1, i32 %0}
call void @llvm.dbg.declare(metadata !{i32* %1}, metadata !{i32 %b, i32 %0})
+; CHECK: metadata !{i32* %1}, metadata !{i32 %b, i32 %0}
call void @llvm.dbg.declare(metadata !{i32 %a}, metadata !{i32 %a, metadata !"foo"})
-; CHECK: metadata !{i32 %a, metadata !"foo"}
+; CHECK: metadata !{i32 %a}, metadata !{i32 %a, metadata !"foo"}
call void @llvm.dbg.declare(metadata !{i32 %b}, metadata !{metadata !0, i32 %two})
+; CHECK: metadata !{i32 %b}, metadata !{metadata !0, i32 %two}
call void @llvm.dbg.value(metadata !{ i32 %a }, i64 0, metadata !1)
+; CHECK: metadata !{i32 %a}, i64 0, metadata !1
call void @llvm.dbg.value(metadata !{ i32 %0 }, i64 25, metadata !0)
+; CHECK: metadata !{i32 %0}, i64 25, metadata !0
call void @llvm.dbg.value(metadata !{ i32* %1 }, i64 16, metadata !"foo")
; CHECK: call void @llvm.dbg.value(metadata !{i32* %1}, i64 16, metadata !"foo")
call void @llvm.dbg.value(metadata !"foo", i64 12, metadata !"bar")
+; CHECK: metadata !"foo", i64 12, metadata !"bar"
ret void, !foo !0, !bar !1
; CHECK: ret void, !foo !0, !bar !1
diff --git a/test/CodeGen/ARM/ctz.ll b/test/CodeGen/ARM/ctz.ll
new file mode 100644
index 0000000..1d2ced3
--- /dev/null
+++ b/test/CodeGen/ARM/ctz.ll
@@ -0,0 +1,11 @@
+; RUN: llc < %s -march=arm -mattr=+v6t2 | FileCheck %s
+
+declare i32 @llvm.cttz.i32(i32)
+
+define i32 @f1(i32 %a) {
+; CHECK: f1:
+; CHECK: rbit
+; CHECK: clz
+ %tmp = call i32 @llvm.cttz.i32( i32 %a )
+ ret i32 %tmp
+}
diff --git a/test/CodeGen/ARM/indirectbr.ll b/test/CodeGen/ARM/indirectbr.ll
index cd16084..5135d03 100644
--- a/test/CodeGen/ARM/indirectbr.ll
+++ b/test/CodeGen/ARM/indirectbr.ll
@@ -12,6 +12,10 @@ define internal arm_apcscc i32 @foo(i32 %i) nounwind {
entry:
%0 = load i8** @nextaddr, align 4 ; <i8*> [#uses=2]
%1 = icmp eq i8* %0, null ; <i1> [#uses=1]
+; indirect branch gets duplicated here
+; ARM: bx
+; THUMB: mov pc, r1
+; THUMB2: mov pc, r1
br i1 %1, label %bb3, label %bb2
bb2: ; preds = %entry, %bb3
diff --git a/test/CodeGen/ARM/vbits.ll b/test/CodeGen/ARM/vbits.ll
index e1d23a1..293d229 100644
--- a/test/CodeGen/ARM/vbits.ll
+++ b/test/CodeGen/ARM/vbits.ll
@@ -442,7 +442,7 @@ define <2 x i64> @v_ornQi64(<2 x i64>* %A, <2 x i64>* %B) nounwind {
define <8 x i8> @vtsti8(<8 x i8>* %A, <8 x i8>* %B) nounwind {
;CHECK: vtsti8:
-;CHECK: vtst.i8
+;CHECK: vtst.8
%tmp1 = load <8 x i8>* %A
%tmp2 = load <8 x i8>* %B
%tmp3 = and <8 x i8> %tmp1, %tmp2
@@ -453,7 +453,7 @@ define <8 x i8> @vtsti8(<8 x i8>* %A, <8 x i8>* %B) nounwind {
define <4 x i16> @vtsti16(<4 x i16>* %A, <4 x i16>* %B) nounwind {
;CHECK: vtsti16:
-;CHECK: vtst.i16
+;CHECK: vtst.16
%tmp1 = load <4 x i16>* %A
%tmp2 = load <4 x i16>* %B
%tmp3 = and <4 x i16> %tmp1, %tmp2
@@ -464,7 +464,7 @@ define <4 x i16> @vtsti16(<4 x i16>* %A, <4 x i16>* %B) nounwind {
define <2 x i32> @vtsti32(<2 x i32>* %A, <2 x i32>* %B) nounwind {
;CHECK: vtsti32:
-;CHECK: vtst.i32
+;CHECK: vtst.32
%tmp1 = load <2 x i32>* %A
%tmp2 = load <2 x i32>* %B
%tmp3 = and <2 x i32> %tmp1, %tmp2
@@ -475,7 +475,7 @@ define <2 x i32> @vtsti32(<2 x i32>* %A, <2 x i32>* %B) nounwind {
define <16 x i8> @vtstQi8(<16 x i8>* %A, <16 x i8>* %B) nounwind {
;CHECK: vtstQi8:
-;CHECK: vtst.i8
+;CHECK: vtst.8
%tmp1 = load <16 x i8>* %A
%tmp2 = load <16 x i8>* %B
%tmp3 = and <16 x i8> %tmp1, %tmp2
@@ -486,7 +486,7 @@ define <16 x i8> @vtstQi8(<16 x i8>* %A, <16 x i8>* %B) nounwind {
define <8 x i16> @vtstQi16(<8 x i16>* %A, <8 x i16>* %B) nounwind {
;CHECK: vtstQi16:
-;CHECK: vtst.i16
+;CHECK: vtst.16
%tmp1 = load <8 x i16>* %A
%tmp2 = load <8 x i16>* %B
%tmp3 = and <8 x i16> %tmp1, %tmp2
@@ -497,7 +497,7 @@ define <8 x i16> @vtstQi16(<8 x i16>* %A, <8 x i16>* %B) nounwind {
define <4 x i32> @vtstQi32(<4 x i32>* %A, <4 x i32>* %B) nounwind {
;CHECK: vtstQi32:
-;CHECK: vtst.i32
+;CHECK: vtst.32
%tmp1 = load <4 x i32>* %A
%tmp2 = load <4 x i32>* %B
%tmp3 = and <4 x i32> %tmp1, %tmp2
diff --git a/test/CodeGen/CellSPU/call_indirect.ll b/test/CodeGen/CellSPU/call_indirect.ll
index f25d6b5..08dad74 100644
--- a/test/CodeGen/CellSPU/call_indirect.ll
+++ b/test/CodeGen/CellSPU/call_indirect.ll
@@ -1,5 +1,5 @@
-; RUN: llc < %s -march=cellspu > %t1.s
-; RUN: llc < %s -march=cellspu -mattr=large_mem > %t2.s
+; RUN: llc < %s -march=cellspu -asm-verbose=0 > %t1.s
+; RUN: llc < %s -march=cellspu -mattr=large_mem -asm-verbose=0 > %t2.s
; RUN: grep bisl %t1.s | count 7
; RUN: grep ila %t1.s | count 1
; RUN: grep rotqby %t1.s | count 5
diff --git a/test/CodeGen/Generic/GC/frame_size.ll b/test/CodeGen/Generic/GC/frame_size.ll
deleted file mode 100644
index 31783cd..0000000
--- a/test/CodeGen/Generic/GC/frame_size.ll
+++ /dev/null
@@ -1,14 +0,0 @@
-; RUN: llc < %s -asm-verbose | grep {frame size} | grep -v 0x0
-
-declare void @llvm.gcroot(i8** %value, i8* %tag)
-declare void @g() gc "ocaml"
-
-define void @f(i8* %arg.0, void()* %arg.1) gc "ocaml" {
-entry:
- %gcroot.0 = alloca i8*
- call void @llvm.gcroot(i8** %gcroot.0, i8* null)
- store i8* %arg.0, i8** %gcroot.0
- call void @g()
- call void %arg.1()
- ret void
-}
diff --git a/test/CodeGen/MSP430/bit.ll b/test/CodeGen/MSP430/bit.ll
index 0dc2158..cd664a1 100644
--- a/test/CodeGen/MSP430/bit.ll
+++ b/test/CodeGen/MSP430/bit.ll
@@ -1,5 +1,4 @@
; RUN: llvm-as < %s | llc -march=msp430 | FileCheck %s
-; XFAIL: *
target datalayout = "e-p:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:16:32"
target triple = "msp430-generic-generic"
diff --git a/test/CodeGen/MSP430/setcc.ll b/test/CodeGen/MSP430/setcc.ll
index ecf0661..9db51cc 100644
--- a/test/CodeGen/MSP430/setcc.ll
+++ b/test/CodeGen/MSP430/setcc.ll
@@ -1,5 +1,4 @@
; RUN: llc -march=msp430 < %s | FileCheck %s
-; XFAIL: *
target datalayout = "e-p:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:16:32"
target triple = "msp430-generic-generic"
@@ -32,7 +31,7 @@ define i16 @sccwne(i16 %a, i16 %b) nounwind {
ret i16 %t2
}
; CHECK:sccwne:
-; CHECK: cmp.w r15, r14
+; CHECK: cmp.w r14, r15
; CHECK-NEXT: mov.w r2, r15
; CHECK-NEXT: rra.w r15
; CHECK-NEXT: and.w #1, r15
@@ -43,7 +42,7 @@ define i16 @sccweq(i16 %a, i16 %b) nounwind {
ret i16 %t2
}
; CHECK:sccweq:
-; CHECK: cmp.w r15, r14
+; CHECK: cmp.w r14, r15
; CHECK-NEXT: mov.w r2, r15
; CHECK-NEXT: rra.w r15
; CHECK-NEXT: and.w #1, r15
@@ -55,7 +54,7 @@ define i16 @sccwugt(i16 %a, i16 %b) nounwind {
ret i16 %t2
}
; CHECK:sccwugt:
-; CHECK: cmp.w r14, r15
+; CHECK: cmp.w r15, r14
; CHECK-NEXT: mov.w r2, r15
; CHECK-NEXT: and.w #1, r15
; CHECK-NEXT: xor.w #1, r15
@@ -66,7 +65,7 @@ define i16 @sccwuge(i16 %a, i16 %b) nounwind {
ret i16 %t2
}
; CHECK:sccwuge:
-; CHECK: cmp.w r15, r14
+; CHECK: cmp.w r14, r15
; CHECK-NEXT: mov.w r2, r15
; CHECK-NEXT: and.w #1, r15
@@ -76,7 +75,7 @@ define i16 @sccwult(i16 %a, i16 %b) nounwind {
ret i16 %t2
}
; CHECK:sccwult:
-; CHECK: cmp.w r15, r14
+; CHECK: cmp.w r14, r15
; CHECK-NEXT: mov.w r2, r15
; CHECK-NEXT: and.w #1, r15
; CHECK-NEXT: xor.w #1, r15
@@ -87,7 +86,7 @@ define i16 @sccwule(i16 %a, i16 %b) nounwind {
ret i16 %t2
}
; CHECK:sccwule:
-; CHECK: cmp.w r14, r15
+; CHECK: cmp.w r15, r14
; CHECK-NEXT: mov.w r2, r15
; CHECK-NEXT: and.w #1, r15
diff --git a/test/CodeGen/PIC16/globals.ll b/test/CodeGen/PIC16/globals.ll
index b8c9116..432c291 100644
--- a/test/CodeGen/PIC16/globals.ll
+++ b/test/CodeGen/PIC16/globals.ll
@@ -2,7 +2,8 @@
@G1 = global i32 4712, section "Address=412"
; CHECK: @G1.412..user_section.# IDATA 412
-; CHECK: @G1 dl 4712
+; CHECK: @G1
+; CHECK: dl 4712
@G2 = global i32 0, section "Address=412"
; CHECK: @G2.412..user_section.# UDATA 412
@@ -10,6 +11,7 @@
@G3 = addrspace(1) constant i32 4712, section "Address=412"
; CHECK: @G3.412..user_section.# ROMDATA 412
-; CHECK: @G3 rom_dl 4712
+; CHECK: @G3
+; CHECK: rom_dl 4712
diff --git a/test/CodeGen/PowerPC/2008-12-12-EH.ll b/test/CodeGen/PowerPC/2008-12-12-EH.ll
index b56c22a..2315e36 100644
--- a/test/CodeGen/PowerPC/2008-12-12-EH.ll
+++ b/test/CodeGen/PowerPC/2008-12-12-EH.ll
@@ -1,4 +1,3 @@
-; RUN: llc < %s -march=ppc32 -mtriple=powerpc-unknown-linux-gnu | grep ^.L_Z1fv.eh
; RUN: llc < %s -march=ppc32 -mtriple=powerpc-apple-darwin9 | grep ^__Z1fv.eh
define void @_Z1fv() {
diff --git a/test/CodeGen/PowerPC/sections.ll b/test/CodeGen/PowerPC/sections.ll
index 1af3709..0ff4a89 100644
--- a/test/CodeGen/PowerPC/sections.ll
+++ b/test/CodeGen/PowerPC/sections.ll
@@ -4,5 +4,5 @@
@A = global i32 0
; CHECK: .section .bss,"aw",@nobits
-; CHECK: .global A
+; CHECK: .globl A
diff --git a/test/CodeGen/PowerPC/stubs.ll b/test/CodeGen/PowerPC/stubs.ll
new file mode 100644
index 0000000..4889263
--- /dev/null
+++ b/test/CodeGen/PowerPC/stubs.ll
@@ -0,0 +1,22 @@
+; RUN: llc %s -o - -mtriple=powerpc-apple-darwin8 | FileCheck %s
+define ppc_fp128 @test1(i64 %X) nounwind readnone {
+entry:
+ %0 = sitofp i64 %X to ppc_fp128
+ ret ppc_fp128 %0
+}
+
+; CHECK: _test1:
+; CHECK: bl ___floatditf$stub
+; CHECK: .section __TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16
+; CHECK: ___floatditf$stub:
+; CHECK: .indirect_symbol ___floatditf
+; CHECK: lis r11,ha16(___floatditf$lazy_ptr)
+; CHECK: lwzu r12,lo16(___floatditf$lazy_ptr)(r11)
+; CHECK: mtctr r12
+; CHECK: bctr
+; CHECK: .section __DATA,__la_symbol_ptr,lazy_symbol_pointers
+; CHECK: ___floatditf$lazy_ptr:
+; CHECK: .indirect_symbol ___floatditf
+; CHECK: .long dyld_stub_binding_helper
+
+
diff --git a/test/CodeGen/Thumb/2009-12-17-pre-regalloc-taildup.ll b/test/CodeGen/Thumb/2009-12-17-pre-regalloc-taildup.ll
index 3401915..2a5d9d6 100644
--- a/test/CodeGen/Thumb/2009-12-17-pre-regalloc-taildup.ll
+++ b/test/CodeGen/Thumb/2009-12-17-pre-regalloc-taildup.ll
@@ -1,4 +1,4 @@
-; RUN: llc -O3 -pre-regalloc-taildup < %s | FileCheck %s
+; RUN: llc -O3 < %s | FileCheck %s
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32"
target triple = "thumbv7-apple-darwin10"
diff --git a/test/CodeGen/Thumb/2010-01-15-local-alloc-spill-physical.ll b/test/CodeGen/Thumb/2010-01-15-local-alloc-spill-physical.ll
new file mode 100644
index 0000000..d676369
--- /dev/null
+++ b/test/CodeGen/Thumb/2010-01-15-local-alloc-spill-physical.ll
@@ -0,0 +1,20 @@
+; RUN: llc < %s -regalloc=local -relocation-model=pic | FileCheck %s
+
+target triple = "thumbv6-apple-darwin10"
+
+@fred = internal global i32 0 ; <i32*> [#uses=1]
+
+define arm_apcscc void @foo() nounwind {
+entry:
+; CHECK: str r0, [sp]
+ %0 = call arm_apcscc i32 (...)* @bar() nounwind ; <i32> [#uses=1]
+; CHECK: blx _bar
+; CHECK: ldr r1, [sp]
+ store i32 %0, i32* @fred, align 4
+ br label %return
+
+return: ; preds = %entry
+ ret void
+}
+
+declare arm_apcscc i32 @bar(...)
diff --git a/test/CodeGen/Thumb2/2010-01-06-TailDuplicateLabels.ll b/test/CodeGen/Thumb2/2010-01-06-TailDuplicateLabels.ll
index 6a05df1..07a3527 100644
--- a/test/CodeGen/Thumb2/2010-01-06-TailDuplicateLabels.ll
+++ b/test/CodeGen/Thumb2/2010-01-06-TailDuplicateLabels.ll
@@ -1,4 +1,4 @@
-; RUN: llc -relocation-model=pic -pre-regalloc-taildup < %s | grep {:$} | sort | uniq -d | count 0
+; RUN: llc -relocation-model=pic < %s | grep {:$} | sort | uniq -d | count 0
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32"
target triple = "thumbv7-apple-darwin10"
diff --git a/test/CodeGen/Thumb2/2010-01-19-RemovePredicates.ll b/test/CodeGen/Thumb2/2010-01-19-RemovePredicates.ll
new file mode 100644
index 0000000..41682c1
--- /dev/null
+++ b/test/CodeGen/Thumb2/2010-01-19-RemovePredicates.ll
@@ -0,0 +1,53 @@
+; RUN: llc -O3 -relocation-model=pic -mcpu=cortex-a8 -mattr=+thumb2 < %s
+;
+; This test creates a predicated t2ADDri instruction that is then turned into a t2MOVgpr2gpr instr.
+; Test that that the predicate operands are removed properly.
+;
+target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32"
+target triple = "thumbv7-apple-darwin10"
+
+declare arm_apcscc void @etoe53(i16* nocapture, i16* nocapture) nounwind
+
+define arm_apcscc void @earith(double* nocapture %value, i32 %icode, double* nocapture %r1, double* nocapture %r2) nounwind {
+entry:
+ %v = alloca [6 x i16], align 4 ; <[6 x i16]*> [#uses=1]
+ br i1 undef, label %bb2.i, label %bb5
+
+bb2.i: ; preds = %entry
+ %0 = bitcast double* %value to i16* ; <i16*> [#uses=1]
+ call arm_apcscc void @etoe53(i16* null, i16* %0) nounwind
+ ret void
+
+bb5: ; preds = %entry
+ switch i32 %icode, label %bb10 [
+ i32 57, label %bb14
+ i32 58, label %bb18
+ i32 67, label %bb22
+ i32 76, label %bb26
+ i32 77, label %bb35
+ ]
+
+bb10: ; preds = %bb5
+ br label %bb46
+
+bb14: ; preds = %bb5
+ unreachable
+
+bb18: ; preds = %bb5
+ unreachable
+
+bb22: ; preds = %bb5
+ unreachable
+
+bb26: ; preds = %bb5
+ br label %bb46
+
+bb35: ; preds = %bb5
+ unreachable
+
+bb46: ; preds = %bb26, %bb10
+ %1 = bitcast double* %value to i16* ; <i16*> [#uses=1]
+ %v47 = getelementptr inbounds [6 x i16]* %v, i32 0, i32 0 ; <i16*> [#uses=1]
+ call arm_apcscc void @etoe53(i16* %v47, i16* %1) nounwind
+ ret void
+}
diff --git a/test/CodeGen/X86/2007-08-13-SpillerReuse.ll b/test/CodeGen/X86/2007-08-13-SpillerReuse.ll
deleted file mode 100644
index d6ea510..0000000
--- a/test/CodeGen/X86/2007-08-13-SpillerReuse.ll
+++ /dev/null
@@ -1,102 +0,0 @@
-; RUN: llc < %s -mtriple=i686-apple-darwin | grep "48(%esp)" | count 5
-
- %struct..0anon = type { i32 }
- %struct.rtvec_def = type { i32, [1 x %struct..0anon] }
- %struct.rtx_def = type { i16, i8, i8, [1 x %struct..0anon] }
-@rtx_format = external global [116 x i8*] ; <[116 x i8*]*> [#uses=1]
-@rtx_length = external global [117 x i32] ; <[117 x i32]*> [#uses=1]
-
-declare %struct.rtx_def* @fixup_memory_subreg(%struct.rtx_def*, %struct.rtx_def*, i32)
-
-define %struct.rtx_def* @walk_fixup_memory_subreg(%struct.rtx_def* %x, %struct.rtx_def* %insn) {
-entry:
- %tmp2 = icmp eq %struct.rtx_def* %x, null ; <i1> [#uses=1]
- br i1 %tmp2, label %UnifiedReturnBlock, label %cond_next
-
-cond_next: ; preds = %entry
- %tmp6 = getelementptr %struct.rtx_def* %x, i32 0, i32 0 ; <i16*> [#uses=1]
- %tmp7 = load i16* %tmp6 ; <i16> [#uses=2]
- %tmp78 = zext i16 %tmp7 to i32 ; <i32> [#uses=2]
- %tmp10 = icmp eq i16 %tmp7, 54 ; <i1> [#uses=1]
- br i1 %tmp10, label %cond_true13, label %cond_next32
-
-cond_true13: ; preds = %cond_next
- %tmp15 = getelementptr %struct.rtx_def* %x, i32 0, i32 3 ; <[1 x %struct..0anon]*> [#uses=1]
- %tmp1718 = bitcast [1 x %struct..0anon]* %tmp15 to %struct.rtx_def** ; <%struct.rtx_def**> [#uses=1]
- %tmp19 = load %struct.rtx_def** %tmp1718 ; <%struct.rtx_def*> [#uses=1]
- %tmp20 = getelementptr %struct.rtx_def* %tmp19, i32 0, i32 0 ; <i16*> [#uses=1]
- %tmp21 = load i16* %tmp20 ; <i16> [#uses=1]
- %tmp22 = icmp eq i16 %tmp21, 57 ; <i1> [#uses=1]
- br i1 %tmp22, label %cond_true25, label %cond_next32
-
-cond_true25: ; preds = %cond_true13
- %tmp29 = tail call %struct.rtx_def* @fixup_memory_subreg( %struct.rtx_def* %x, %struct.rtx_def* %insn, i32 1 ) ; <%struct.rtx_def*> [#uses=1]
- ret %struct.rtx_def* %tmp29
-
-cond_next32: ; preds = %cond_true13, %cond_next
- %tmp34 = getelementptr [116 x i8*]* @rtx_format, i32 0, i32 %tmp78 ; <i8**> [#uses=1]
- %tmp35 = load i8** %tmp34, align 4 ; <i8*> [#uses=1]
- %tmp37 = getelementptr [117 x i32]* @rtx_length, i32 0, i32 %tmp78 ; <i32*> [#uses=1]
- %tmp38 = load i32* %tmp37, align 4 ; <i32> [#uses=1]
- %i.011 = add i32 %tmp38, -1 ; <i32> [#uses=2]
- %tmp12513 = icmp sgt i32 %i.011, -1 ; <i1> [#uses=1]
- br i1 %tmp12513, label %bb, label %UnifiedReturnBlock
-
-bb: ; preds = %bb123, %cond_next32
- %indvar = phi i32 [ %indvar.next26, %bb123 ], [ 0, %cond_next32 ] ; <i32> [#uses=2]
- %i.01.0 = sub i32 %i.011, %indvar ; <i32> [#uses=5]
- %tmp42 = getelementptr i8* %tmp35, i32 %i.01.0 ; <i8*> [#uses=2]
- %tmp43 = load i8* %tmp42 ; <i8> [#uses=1]
- switch i8 %tmp43, label %bb123 [
- i8 101, label %cond_true47
- i8 69, label %bb105.preheader
- ]
-
-cond_true47: ; preds = %bb
- %tmp52 = getelementptr %struct.rtx_def* %x, i32 0, i32 3, i32 %i.01.0 ; <%struct..0anon*> [#uses=1]
- %tmp5354 = bitcast %struct..0anon* %tmp52 to %struct.rtx_def** ; <%struct.rtx_def**> [#uses=1]
- %tmp55 = load %struct.rtx_def** %tmp5354 ; <%struct.rtx_def*> [#uses=1]
- %tmp58 = tail call %struct.rtx_def* @walk_fixup_memory_subreg( %struct.rtx_def* %tmp55, %struct.rtx_def* %insn ) ; <%struct.rtx_def*> [#uses=1]
- %tmp62 = getelementptr %struct.rtx_def* %x, i32 0, i32 3, i32 %i.01.0, i32 0 ; <i32*> [#uses=1]
- %tmp58.c = ptrtoint %struct.rtx_def* %tmp58 to i32 ; <i32> [#uses=1]
- store i32 %tmp58.c, i32* %tmp62
- %tmp6816 = load i8* %tmp42 ; <i8> [#uses=1]
- %tmp6917 = icmp eq i8 %tmp6816, 69 ; <i1> [#uses=1]
- br i1 %tmp6917, label %bb105.preheader, label %bb123
-
-bb105.preheader: ; preds = %cond_true47, %bb
- %tmp11020 = getelementptr %struct.rtx_def* %x, i32 0, i32 3, i32 %i.01.0 ; <%struct..0anon*> [#uses=1]
- %tmp11111221 = bitcast %struct..0anon* %tmp11020 to %struct.rtvec_def** ; <%struct.rtvec_def**> [#uses=3]
- %tmp11322 = load %struct.rtvec_def** %tmp11111221 ; <%struct.rtvec_def*> [#uses=1]
- %tmp11423 = getelementptr %struct.rtvec_def* %tmp11322, i32 0, i32 0 ; <i32*> [#uses=1]
- %tmp11524 = load i32* %tmp11423 ; <i32> [#uses=1]
- %tmp11625 = icmp eq i32 %tmp11524, 0 ; <i1> [#uses=1]
- br i1 %tmp11625, label %bb123, label %bb73
-
-bb73: ; preds = %bb73, %bb105.preheader
- %j.019 = phi i32 [ %tmp104, %bb73 ], [ 0, %bb105.preheader ] ; <i32> [#uses=3]
- %tmp81 = load %struct.rtvec_def** %tmp11111221 ; <%struct.rtvec_def*> [#uses=2]
- %tmp92 = getelementptr %struct.rtvec_def* %tmp81, i32 0, i32 1, i32 %j.019 ; <%struct..0anon*> [#uses=1]
- %tmp9394 = bitcast %struct..0anon* %tmp92 to %struct.rtx_def** ; <%struct.rtx_def**> [#uses=1]
- %tmp95 = load %struct.rtx_def** %tmp9394 ; <%struct.rtx_def*> [#uses=1]
- %tmp98 = tail call %struct.rtx_def* @walk_fixup_memory_subreg( %struct.rtx_def* %tmp95, %struct.rtx_def* %insn ) ; <%struct.rtx_def*> [#uses=1]
- %tmp101 = getelementptr %struct.rtvec_def* %tmp81, i32 0, i32 1, i32 %j.019, i32 0 ; <i32*> [#uses=1]
- %tmp98.c = ptrtoint %struct.rtx_def* %tmp98 to i32 ; <i32> [#uses=1]
- store i32 %tmp98.c, i32* %tmp101
- %tmp104 = add i32 %j.019, 1 ; <i32> [#uses=2]
- %tmp113 = load %struct.rtvec_def** %tmp11111221 ; <%struct.rtvec_def*> [#uses=1]
- %tmp114 = getelementptr %struct.rtvec_def* %tmp113, i32 0, i32 0 ; <i32*> [#uses=1]
- %tmp115 = load i32* %tmp114 ; <i32> [#uses=1]
- %tmp116 = icmp ult i32 %tmp104, %tmp115 ; <i1> [#uses=1]
- br i1 %tmp116, label %bb73, label %bb123
-
-bb123: ; preds = %bb73, %bb105.preheader, %cond_true47, %bb
- %i.0 = add i32 %i.01.0, -1 ; <i32> [#uses=1]
- %tmp125 = icmp sgt i32 %i.0, -1 ; <i1> [#uses=1]
- %indvar.next26 = add i32 %indvar, 1 ; <i32> [#uses=1]
- br i1 %tmp125, label %bb, label %UnifiedReturnBlock
-
-UnifiedReturnBlock: ; preds = %bb123, %cond_next32, %entry
- %UnifiedRetVal = phi %struct.rtx_def* [ null, %entry ], [ %x, %cond_next32 ], [ %x, %bb123 ] ; <%struct.rtx_def*> [#uses=1]
- ret %struct.rtx_def* %UnifiedRetVal
-}
diff --git a/test/CodeGen/X86/2008-04-02-unnamedEH.ll b/test/CodeGen/X86/2008-04-02-unnamedEH.ll
index a9f368b..27bbbaa 100644
--- a/test/CodeGen/X86/2008-04-02-unnamedEH.ll
+++ b/test/CodeGen/X86/2008-04-02-unnamedEH.ll
@@ -1,26 +1,16 @@
-; RUN: llc < %s | grep unnamed_1.eh
+; RUN: llc < %s | FileCheck %s
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:128:128"
target triple = "i386-apple-darwin8"
define void @_Z3bazv() {
- call i32 @0( ) ; <i32>:1 [#uses=0]
- br label %2
-; <label>:2 ; preds = %0
+ call void @0( ) ; <i32>:1 [#uses=0]
ret void
}
-define internal i32 @""() {
- alloca i32 ; <i32*>:1 [#uses=2]
- alloca i32 ; <i32*>:2 [#uses=2]
- bitcast i32 0 to i32 ; <i32>:3 [#uses=0]
+define internal void @""() {
call i32 @_Z3barv( ) ; <i32>:4 [#uses=1]
- store i32 %4, i32* %2, align 4
- load i32* %2, align 4 ; <i32>:5 [#uses=1]
- store i32 %5, i32* %1, align 4
- br label %6
-; <label>:6 ; preds = %0
- load i32* %1 ; <i32>:7 [#uses=1]
- ret i32 %7
+ ret void
}
+; CHECK: unnamed_1.eh
declare i32 @_Z3barv()
diff --git a/test/CodeGen/X86/2008-09-18-inline-asm-2.ll b/test/CodeGen/X86/2008-09-18-inline-asm-2.ll
index f5bd307..e3b6fdf 100644
--- a/test/CodeGen/X86/2008-09-18-inline-asm-2.ll
+++ b/test/CodeGen/X86/2008-09-18-inline-asm-2.ll
@@ -1,5 +1,5 @@
-; RUN: llc < %s -march=x86 | grep "#%ebp %edi %esi 8(%edx) %eax (%ebx)"
-; RUN: llc < %s -march=x86 -regalloc=local | grep "#%edi %edx %ebp 8(%ebx) %eax (%esi)"
+; RUN: llc < %s -march=x86 | grep "#%ebp %esi %edi 8(%edx) %eax (%ebx)"
+; RUN: llc < %s -march=x86 -regalloc=local | grep "#%edi %ebp %edx 8(%ebx) %eax (%esi)"
; The 1st, 2nd, 3rd and 5th registers above must all be different. The registers
; referenced in the 4th and 6th operands must not be the same as the 1st or 5th
; operand. There are many combinations that work; this is what llc puts out now.
diff --git a/test/CodeGen/X86/2008-12-19-EarlyClobberBug.ll b/test/CodeGen/X86/2008-12-19-EarlyClobberBug.ll
index 13a9080..a6cabc4 100644
--- a/test/CodeGen/X86/2008-12-19-EarlyClobberBug.ll
+++ b/test/CodeGen/X86/2008-12-19-EarlyClobberBug.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=i386-apple-darwin | FileCheck %s
+; RUN: llc < %s -mtriple=i386-apple-darwin -asm-verbose=0 | FileCheck %s
; PR3149
; Make sure the copy after inline asm is not coalesced away.
diff --git a/test/CodeGen/X86/2009-02-04-sext-i64-gep.ll b/test/CodeGen/X86/2009-02-04-sext-i64-gep.ll
index 6ba046a..4880f62 100644
--- a/test/CodeGen/X86/2009-02-04-sext-i64-gep.ll
+++ b/test/CodeGen/X86/2009-02-04-sext-i64-gep.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s | grep { - 92}
+; RUN: llc < %s | grep p-92
; PR3481
; The offset should print as -92, not +17179869092
diff --git a/test/CodeGen/X86/2009-09-10-SpillComments.ll b/test/CodeGen/X86/2009-09-10-SpillComments.ll
index 1dd9990..f9ca861 100644
--- a/test/CodeGen/X86/2009-09-10-SpillComments.ll
+++ b/test/CodeGen/X86/2009-09-10-SpillComments.ll
@@ -1,5 +1,11 @@
; RUN: llc < %s -mtriple=x86_64-unknown-linux | FileCheck %s
+; This test shouldn't require spills.
+
+; CHECK: subq $8, %rsp
+; CHECK-NOT: $rsp
+; CHECK: addq $8, %rsp
+
%struct..0anon = type { i32 }
%struct.rtvec_def = type { i32, [1 x %struct..0anon] }
%struct.rtx_def = type { i16, i8, i8, [1 x %struct..0anon] }
@@ -10,9 +16,6 @@ declare %struct.rtx_def* @fixup_memory_subreg(%struct.rtx_def*, %struct.rtx_def*
define %struct.rtx_def* @walk_fixup_memory_subreg(%struct.rtx_def* %x, %struct.rtx_def* %insn) {
entry:
-; CHECK: Spill
-; CHECK: Folded Spill
-; CHECK: Reload
%tmp2 = icmp eq %struct.rtx_def* %x, null ; <i1> [#uses=1]
br i1 %tmp2, label %UnifiedReturnBlock, label %cond_next
diff --git a/test/CodeGen/X86/2010-01-15-SelectionDAGCycle.ll b/test/CodeGen/X86/2010-01-15-SelectionDAGCycle.ll
new file mode 100644
index 0000000..5d96e4a
--- /dev/null
+++ b/test/CodeGen/X86/2010-01-15-SelectionDAGCycle.ll
@@ -0,0 +1,28 @@
+; RUN: llc < %s -march=x86-64
+; ModuleID = 'bugpoint-reduced-simplified.bc'
+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"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @numvec_(i32* noalias %ncelet, i32* noalias %ncel, i32* noalias %nfac, i32* noalias %nfabor, i32* noalias %lregis, i32* noalias %irveci, i32* noalias %irvecb, [0 x [2 x i32]]* noalias %ifacel, [0 x i32]* noalias %ifabor, [0 x i32]* noalias %inumfi, [0 x i32]* noalias %inumfb, [1 x i32]* noalias %iworkf, [0 x i32]* noalias %ismbs) {
+"file bug754399.f90, line 1, bb1":
+ %r1037 = bitcast <2 x double> zeroinitializer to <4 x i32> ; <<4 x i32>> [#uses=1]
+ br label %"file bug754399.f90, line 184, in inner vector loop at depth 0, bb164"
+
+"file bug754399.f90, line 184, in inner vector loop at depth 0, bb164": ; preds = %"file bug754399.f90, line 184, in inner vector loop at depth 0, bb164", %"file bug754399.f90, line 1, bb1"
+ %tmp641 = add i64 0, 48 ; <i64> [#uses=1]
+ %tmp641642 = inttoptr i64 %tmp641 to <4 x i32>* ; <<4 x i32>*> [#uses=1]
+ %r1258 = load <4 x i32>* %tmp641642, align 4 ; <<4 x i32>> [#uses=2]
+ %r1295 = extractelement <4 x i32> %r1258, i32 3 ; <i32> [#uses=1]
+ %r1296 = sext i32 %r1295 to i64 ; <i64> [#uses=1]
+ %r1297 = add i64 %r1296, -1 ; <i64> [#uses=1]
+ %r1298183 = getelementptr [0 x i32]* %ismbs, i64 0, i64 %r1297 ; <i32*> [#uses=1]
+ %r1298184 = load i32* %r1298183, align 4 ; <i32> [#uses=1]
+ %r1301 = extractelement <4 x i32> %r1037, i32 3 ; <i32> [#uses=1]
+ %r1302 = mul i32 %r1298184, %r1301 ; <i32> [#uses=1]
+ %r1306 = insertelement <4 x i32> zeroinitializer, i32 %r1302, i32 3 ; <<4 x i32>> [#uses=1]
+ %r1321 = add <4 x i32> %r1306, %r1258 ; <<4 x i32>> [#uses=1]
+ %tmp643 = add i64 0, 48 ; <i64> [#uses=1]
+ %tmp643644 = inttoptr i64 %tmp643 to <4 x i32>* ; <<4 x i32>*> [#uses=1]
+ store <4 x i32> %r1321, <4 x i32>* %tmp643644, align 4
+ br label %"file bug754399.f90, line 184, in inner vector loop at depth 0, bb164"
+}
diff --git a/test/CodeGen/X86/2010-01-19-OptExtBug.ll b/test/CodeGen/X86/2010-01-19-OptExtBug.ll
new file mode 100644
index 0000000..cd8960b
--- /dev/null
+++ b/test/CodeGen/X86/2010-01-19-OptExtBug.ll
@@ -0,0 +1,57 @@
+; RUN: llc < %s -mtriple=x86_64-apple-darwin11 -relocation-model=pic -disable-fp-elim -stats |& not grep ext-opt
+
+define fastcc i8* @S_scan_str(i8* %start, i32 %keep_quoted, i32 %keep_delims) nounwind ssp {
+entry:
+ switch i8 undef, label %bb6 [
+ i8 9, label %bb5
+ i8 32, label %bb5
+ i8 10, label %bb5
+ i8 13, label %bb5
+ i8 12, label %bb5
+ ]
+
+bb5: ; preds = %entry, %entry, %entry, %entry, %entry
+ br label %bb6
+
+bb6: ; preds = %bb5, %entry
+ br i1 undef, label %bb7, label %bb9
+
+bb7: ; preds = %bb6
+ unreachable
+
+bb9: ; preds = %bb6
+ %0 = load i8* undef, align 1 ; <i8> [#uses=3]
+ br i1 undef, label %bb12, label %bb10
+
+bb10: ; preds = %bb9
+ br i1 undef, label %bb12, label %bb11
+
+bb11: ; preds = %bb10
+ unreachable
+
+bb12: ; preds = %bb10, %bb9
+ br i1 undef, label %bb13, label %bb14
+
+bb13: ; preds = %bb12
+ store i8 %0, i8* undef, align 1
+ %1 = zext i8 %0 to i32 ; <i32> [#uses=1]
+ br label %bb18
+
+bb14: ; preds = %bb12
+ br label %bb18
+
+bb18: ; preds = %bb14, %bb13
+ %termcode.0 = phi i32 [ %1, %bb13 ], [ undef, %bb14 ] ; <i32> [#uses=2]
+ %2 = icmp eq i8 %0, 0 ; <i1> [#uses=1]
+ br i1 %2, label %bb21, label %bb19
+
+bb19: ; preds = %bb18
+ br i1 undef, label %bb21, label %bb20
+
+bb20: ; preds = %bb19
+ br label %bb21
+
+bb21: ; preds = %bb20, %bb19, %bb18
+ %termcode.1 = phi i32 [ %termcode.0, %bb18 ], [ %termcode.0, %bb19 ], [ undef, %bb20 ] ; <i32> [#uses=0]
+ unreachable
+}
diff --git a/test/CodeGen/X86/bigstructret2.ll b/test/CodeGen/X86/bigstructret2.ll
new file mode 100644
index 0000000..46e0fd2
--- /dev/null
+++ b/test/CodeGen/X86/bigstructret2.ll
@@ -0,0 +1,12 @@
+; RUN: llc < %s -march=x86 -o %t
+
+%0 = type { i64, i64 }
+
+declare fastcc %0 @ReturnBigStruct() nounwind readnone
+
+define void @test(%0* %p) {
+ %1 = call fastcc %0 @ReturnBigStruct()
+ store %0 %1, %0* %p
+ ret void
+}
+
diff --git a/test/CodeGen/X86/bss_pagealigned.ll b/test/CodeGen/X86/bss_pagealigned.ll
index 27c5361..da95aca 100644
--- a/test/CodeGen/X86/bss_pagealigned.ll
+++ b/test/CodeGen/X86/bss_pagealigned.ll
@@ -1,4 +1,4 @@
-; RUN: llc --code-model=kernel -march=x86-64 <%s | FileCheck %s
+; RUN: llc --code-model=kernel -march=x86-64 <%s -asm-verbose=0 | FileCheck %s
; PR4933
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"
target triple = "x86_64-unknown-linux-gnu"
diff --git a/test/CodeGen/X86/full-lsr.ll b/test/CodeGen/X86/full-lsr.ll
index 68575bc..3bd58b6 100644
--- a/test/CodeGen/X86/full-lsr.ll
+++ b/test/CodeGen/X86/full-lsr.ll
@@ -1,6 +1,12 @@
-; RUN: llc < %s -march=x86 -enable-full-lsr >%t
-; RUN: grep {addl \\\$4,} %t | count 3
-; RUN: not grep {,%} %t
+; RUN: llc < %s -march=x86 >%t
+
+; TODO: Enhance full lsr mode to get this:
+; RUNX: grep {addl \\\$4,} %t | count 3
+; RUNX: not grep {,%} %t
+
+; For now, it should find this, which is still pretty good:
+; RUN: not grep {addl \\\$4,} %t
+; RUN: grep {,%} %t | count 6
define void @foo(float* nocapture %A, float* nocapture %B, float* nocapture %C, i32 %N) nounwind {
entry:
diff --git a/test/CodeGen/X86/global-sections.ll b/test/CodeGen/X86/global-sections.ll
index 38948a7..1a7b577 100644
--- a/test/CodeGen/X86/global-sections.ll
+++ b/test/CodeGen/X86/global-sections.ll
@@ -6,7 +6,6 @@
@G1 = common global i32 0
; LINUX: .type G1,@object
-; LINUX: .section .gnu.linkonce.b.G1,"aw",@nobits
; LINUX: .comm G1,4,4
; DARWIN: .comm _G1,4,2
@@ -76,14 +75,14 @@
; LINUX: .section .gnu.linkonce.r.G6,"a",@progbits
; LINUX: .weak G6
; LINUX: G6:
-; LINUX: .ascii "\001"
+; LINUX: .byte 1
; LINUX: .size G6, 1
; DARWIN: .section __TEXT,__const_coal,coalesced
; DARWIN: .globl _G6
; DARWIN: .weak_definition _G6
; DARWIN:_G6:
-; DARWIN: .ascii "\001"
+; DARWIN: .byte 1
@G7 = constant [10 x i8] c"abcdefghi\00"
@@ -120,4 +119,19 @@
; LINUX:G9
+@G10 = weak global [100 x i32] zeroinitializer, align 32 ; <[100 x i32]*> [#uses=0]
+
+
+; DARWIN: .section __DATA,__datacoal_nt,coalesced
+; DARWIN: .globl _G10
+; DARWIN: .weak_definition _G10
+; DARWIN: .align 5
+; DARWIN: _G10:
+; DARWIN: .space 400
+
+; LINUX: .bss
+; LINUX: .weak G10
+; LINUX: .align 32
+; LINUX: G10:
+; LINUX: .zero 400
diff --git a/test/CodeGen/X86/i128-and-beyond.ll b/test/CodeGen/X86/i128-and-beyond.ll
index 907a6b8..b741681 100644
--- a/test/CodeGen/X86/i128-and-beyond.ll
+++ b/test/CodeGen/X86/i128-and-beyond.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=x86 -mtriple=i686-pc-linux-gnu | grep 18446744073709551615 | count 14
+; RUN: llc < %s -march=x86 -mtriple=i686-pc-linux-gnu | grep -- -1 | count 14
; These static initializers are too big to hand off to assemblers
; as monolithic blobs.
diff --git a/test/CodeGen/X86/illegal-asm.ll b/test/CodeGen/X86/illegal-asm.ll
deleted file mode 100644
index 43128dc..0000000
--- a/test/CodeGen/X86/illegal-asm.ll
+++ /dev/null
@@ -1,34 +0,0 @@
-; RUN: llc < %s -mtriple=i386-apple-darwin -disable-fp-elim
-; RUN: llc < %s -mtriple=i386-linux -disable-fp-elim
-; XFAIL: *
-; Expected to run out of registers during allocation.
-; PR3864
-; rdar://6251720
-
- %struct.CABACContext = type { i32, i32, i8* }
- %struct.H264Context = type { %struct.CABACContext, [460 x i8] }
-@coeff_abs_level_m1_offset = common global [6 x i32] zeroinitializer ; <[6 x i32]*> [#uses=1]
-@coeff_abs_level1_ctx = common global [8 x i8] zeroinitializer ; <[8 x i8]*> [#uses=1]
-
-define i32 @decode_cabac_residual(%struct.H264Context* %h, i32 %cat) nounwind {
-entry:
- %0 = getelementptr [6 x i32]* @coeff_abs_level_m1_offset, i32 0, i32 %cat ; <i32*> [#uses=1]
- %1 = load i32* %0, align 4 ; <i32> [#uses=1]
- %2 = load i8* getelementptr ([8 x i8]* @coeff_abs_level1_ctx, i32 0, i32 0), align 1 ; <i8> [#uses=1]
- %3 = zext i8 %2 to i32 ; <i32> [#uses=1]
- %.sum = add i32 %3, %1 ; <i32> [#uses=1]
- %4 = getelementptr %struct.H264Context* %h, i32 0, i32 1, i32 %.sum ; <i8*> [#uses=2]
- %5 = getelementptr %struct.H264Context* %h, i32 0, i32 0, i32 0 ; <i32*> [#uses=2]
- %6 = getelementptr %struct.H264Context* %h, i32 0, i32 0, i32 1 ; <i32*> [#uses=2]
- %7 = getelementptr %struct.H264Context* %h, i32 0, i32 0, i32 2 ; <i8**> [#uses=2]
- %8 = load i32* %5, align 4 ; <i32> [#uses=1]
- %9 = load i32* %6, align 4 ; <i32> [#uses=1]
- %10 = load i8* %4, align 4 ; <i8> [#uses=1]
- %asmtmp = tail call { i32, i32, i32, i32 } asm sideeffect "#$0 $1 $2 $3 $4 $5", "=&{di},=r,=r,=*m,=&q,=*imr,1,2,*m,5,~{dirflag},~{fpsr},~{flags},~{cx}"(i8** %7, i8* %4, i32 %8, i32 %9, i8** %7, i8 %10) nounwind ; <{ i32, i32, i32, i32 }> [#uses=3]
- %asmresult = extractvalue { i32, i32, i32, i32 } %asmtmp, 0 ; <i32> [#uses=1]
- %asmresult1 = extractvalue { i32, i32, i32, i32 } %asmtmp, 1 ; <i32> [#uses=1]
- store i32 %asmresult1, i32* %5
- %asmresult2 = extractvalue { i32, i32, i32, i32 } %asmtmp, 2 ; <i32> [#uses=1]
- store i32 %asmresult2, i32* %6
- ret i32 %asmresult
-}
diff --git a/test/CodeGen/X86/loop-hoist.ll b/test/CodeGen/X86/loop-hoist.ll
index b52066d..b9008e5 100644
--- a/test/CodeGen/X86/loop-hoist.ll
+++ b/test/CodeGen/X86/loop-hoist.ll
@@ -4,7 +4,7 @@
; CHECK: _foo:
; CHECK: L_Arr$non_lazy_ptr
-; CHECK: LBB1_1: ## %cond_true
+; CHECK: LBB1_1:
@Arr = external global [0 x i32] ; <[0 x i32]*> [#uses=1]
diff --git a/test/CodeGen/X86/loop-strength-reduce4.ll b/test/CodeGen/X86/loop-strength-reduce4.ll
index 87b606f..07e46ec 100644
--- a/test/CodeGen/X86/loop-strength-reduce4.ll
+++ b/test/CodeGen/X86/loop-strength-reduce4.ll
@@ -4,7 +4,7 @@
@state = external global [0 x i32] ; <[0 x i32]*> [#uses=4]
@S = external global [0 x i32] ; <[0 x i32]*> [#uses=4]
-define i32 @foo() {
+define i32 @foo() nounwind {
entry:
br label %bb
diff --git a/test/CodeGen/X86/neg-shl-add.ll b/test/CodeGen/X86/neg-shl-add.ll
new file mode 100644
index 0000000..7aebc38
--- /dev/null
+++ b/test/CodeGen/X86/neg-shl-add.ll
@@ -0,0 +1,17 @@
+; RUN: llc -march=x86-64 < %s | not grep negq
+
+; These sequences don't need neg instructions; they can be done with
+; a single shift and sub each.
+
+define i64 @foo(i64 %x, i64 %y, i64 %n) nounwind {
+ %a = sub i64 0, %y
+ %b = shl i64 %a, %n
+ %c = add i64 %b, %x
+ ret i64 %c
+}
+define i64 @boo(i64 %x, i64 %y, i64 %n) nounwind {
+ %a = sub i64 0, %y
+ %b = shl i64 %a, %n
+ %c = add i64 %x, %b
+ ret i64 %c
+}
diff --git a/test/CodeGen/X86/pr3495-2.ll b/test/CodeGen/X86/pr3495-2.ll
index 1372a15..71aa5a0 100644
--- a/test/CodeGen/X86/pr3495-2.ll
+++ b/test/CodeGen/X86/pr3495-2.ll
@@ -1,5 +1,6 @@
; RUN: llc < %s -march=x86 -relocation-model=pic -disable-fp-elim -stats |& grep {Number of reloads omited}
+target datalayout = "e-p:32:32:32"
target triple = "i386-apple-darwin9.6"
%struct.constraintVCGType = type { i32, i32, i32, i32 }
%struct.nodeVCGType = type { %struct.constraintVCGType*, i32, i32, i32, %struct.constraintVCGType*, i32, i32, i32 }
diff --git a/test/CodeGen/X86/pr3495.ll b/test/CodeGen/X86/pr3495.ll
index 4b62bf4..1795970 100644
--- a/test/CodeGen/X86/pr3495.ll
+++ b/test/CodeGen/X86/pr3495.ll
@@ -1,6 +1,6 @@
-; RUN: llc < %s -march=x86 -stats |& grep {Number of reloads omited} | grep 1
-; RUN: llc < %s -march=x86 -stats |& grep {Number of available reloads turned into copies} | grep 1
-; RUN: llc < %s -march=x86 -stats |& grep {Number of machine instrs printed} | grep 40
+; RUN: llc < %s -march=x86 -stats |& grep {Number of loads added} | grep 2
+; RUN: llc < %s -march=x86 -stats |& grep {Number of register spills} | grep 1
+; RUN: llc < %s -march=x86 -stats |& grep {Number of machine instrs printed} | grep 38
; PR3495
; The loop reversal kicks in once here, resulting in one fewer instruction.
diff --git a/test/CodeGen/X86/ptrtoint-constexpr.ll b/test/CodeGen/X86/ptrtoint-constexpr.ll
index 72a428e..7e33e79 100644
--- a/test/CodeGen/X86/ptrtoint-constexpr.ll
+++ b/test/CodeGen/X86/ptrtoint-constexpr.ll
@@ -3,6 +3,6 @@
; CHECK: .globl r
; CHECK: r:
-; CHECK: .quad ((r) & 4294967295)
+; CHECK: .quad r&4294967295
@r = global %union.x { i64 ptrtoint (%union.x* @r to i64) }, align 4
diff --git a/test/CodeGen/X86/remat-mov-0.ll b/test/CodeGen/X86/remat-mov-0.ll
index c4f768c..5fb445c 100644
--- a/test/CodeGen/X86/remat-mov-0.ll
+++ b/test/CodeGen/X86/remat-mov-0.ll
@@ -1,13 +1,33 @@
-; RUN: llc < %s -march=x86-64 | grep {xorl %edi, %edi} | count 4
+; RUN: llc < %s -march=x86-64 | FileCheck %s
; CodeGen should remat the zero instead of spilling it.
declare void @foo(i64 %p)
+; CHECK: bar:
+; CHECK: xorl %edi, %edi
+; CHECK: xorl %edi, %edi
define void @bar() nounwind {
call void @foo(i64 0)
call void @foo(i64 0)
- call void @foo(i64 0)
- call void @foo(i64 0)
ret void
}
+
+; CHECK: bat:
+; CHECK: movq $-1, %rdi
+; CHECK: movq $-1, %rdi
+define void @bat() nounwind {
+ call void @foo(i64 -1)
+ call void @foo(i64 -1)
+ ret void
+}
+
+; CHECK: bau:
+; CHECK: movl $1, %edi
+; CHECK: movl $1, %edi
+define void @bau() nounwind {
+ call void @foo(i64 1)
+ call void @foo(i64 1)
+ ret void
+}
+
diff --git a/test/CodeGen/X86/remat-mov-1.ll b/test/CodeGen/X86/remat-mov-1.ll
deleted file mode 100644
index d71b7a5..0000000
--- a/test/CodeGen/X86/remat-mov-1.ll
+++ /dev/null
@@ -1,40 +0,0 @@
-; RUN: llc < %s -march=x86 | grep -- -1 | grep mov | count 2
-
- %struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
- %struct.ImgT = type { i8, i8*, i8*, %struct.FILE*, i32, i32, i32, i32, i8*, double*, float*, float*, float*, i32*, double, double, i32*, double*, i32*, i32* }
- %struct._CompT = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, float, float, i8, %struct._PixT*, %struct._CompT*, i8, %struct._CompT* }
- %struct._PixT = type { i32, i32, %struct._PixT* }
- %struct.__sFILEX = type opaque
- %struct.__sbuf = type { i8*, i32 }
-
-declare fastcc void @MergeComponents(%struct._CompT*, %struct._CompT*, %struct._CompT*, %struct._CompT**, %struct.ImgT*) nounwind
-
-define fastcc void @MergeToLeft(%struct._CompT* %comp, %struct._CompT** %head, %struct.ImgT* %img) nounwind {
-entry:
- br label %bb208
-
-bb105: ; preds = %bb200
- br i1 false, label %bb197, label %bb149
-
-bb149: ; preds = %bb105
- %tmp151 = getelementptr %struct._CompT* %comp, i32 0, i32 0 ; <i32*> [#uses=1]
- br label %bb193
-
-bb193: ; preds = %bb184, %bb149
- %tmp196 = load i32* %tmp151, align 4 ; <i32> [#uses=1]
- br label %bb197
-
-bb197: ; preds = %bb193, %bb105
- %last_comp.0 = phi i32 [ %tmp196, %bb193 ], [ 0, %bb105 ] ; <i32> [#uses=0]
- %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1]
- br label %bb200
-
-bb200: ; preds = %bb208, %bb197
- %indvar = phi i32 [ 0, %bb208 ], [ %indvar.next, %bb197 ] ; <i32> [#uses=2]
- %xm.0 = sub i32 %indvar, 0 ; <i32> [#uses=1]
- %tmp202 = icmp slt i32 %xm.0, 1 ; <i1> [#uses=1]
- br i1 %tmp202, label %bb105, label %bb208
-
-bb208: ; preds = %bb200, %entry
- br label %bb200
-}
diff --git a/test/CodeGen/X86/remat-scalar-zero.ll b/test/CodeGen/X86/remat-scalar-zero.ll
index 790ae83..2da96ab 100644
--- a/test/CodeGen/X86/remat-scalar-zero.ll
+++ b/test/CodeGen/X86/remat-scalar-zero.ll
@@ -1,7 +1,7 @@
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu > %t
; RUN: not grep xor %t
; RUN: not grep movap %t
-; RUN: grep {\\.zero} %t
+; RUN: grep {\\.quad.*0} %t
; Remat should be able to fold the zero constant into the div instructions
; as a constant-pool load.
diff --git a/test/CodeGen/X86/splat-scalar-load.ll b/test/CodeGen/X86/splat-scalar-load.ll
index 32d3ab6..2b13029 100644
--- a/test/CodeGen/X86/splat-scalar-load.ll
+++ b/test/CodeGen/X86/splat-scalar-load.ll
@@ -1,21 +1,6 @@
; RUN: llc < %s -mtriple=i386-apple-darwin -mattr=+sse2 | FileCheck %s
; rdar://7434544
-define <2 x i64> @t1() nounwind ssp {
-entry:
-; CHECK: t1:
-; CHECK: pshufd $0, (%esp), %xmm0
- %array = alloca [8 x float], align 16
- %arrayidx = getelementptr inbounds [8 x float]* %array, i32 0, i32 0
- %tmp2 = load float* %arrayidx
- %vecinit = insertelement <4 x float> undef, float %tmp2, i32 0
- %vecinit5 = insertelement <4 x float> %vecinit, float %tmp2, i32 1
- %vecinit7 = insertelement <4 x float> %vecinit5, float %tmp2, i32 2
- %vecinit9 = insertelement <4 x float> %vecinit7, float %tmp2, i32 3
- %0 = bitcast <4 x float> %vecinit9 to <2 x i64>
- ret <2 x i64> %0
-}
-
define <2 x i64> @t2() nounwind ssp {
entry:
; CHECK: t2:
@@ -30,14 +15,3 @@ entry:
%0 = bitcast <4 x float> %vecinit9 to <2 x i64>
ret <2 x i64> %0
}
-
-define <4 x float> @t3(float %tmp1, float %tmp2, float %tmp3) nounwind readnone ssp {
-entry:
-; CHECK: t3:
-; CHECK: pshufd $-86, (%esp), %xmm0
- %0 = insertelement <4 x float> undef, float %tmp3, i32 0
- %1 = insertelement <4 x float> %0, float %tmp3, i32 1
- %2 = insertelement <4 x float> %1, float %tmp3, i32 2
- %3 = insertelement <4 x float> %2, float %tmp3, i32 3
- ret <4 x float> %3
-}
diff --git a/test/CodeGen/X86/stride-reuse.ll b/test/CodeGen/X86/stride-reuse.ll
index a99a9c9..5cbd895 100644
--- a/test/CodeGen/X86/stride-reuse.ll
+++ b/test/CodeGen/X86/stride-reuse.ll
@@ -5,7 +5,7 @@
@A = external global [1000 x float], align 32
@P = external global [1000 x i32], align 32
-define void @foo(i32 %m) {
+define void @foo(i32 %m) nounwind {
entry:
%tmp1 = icmp sgt i32 %m, 0
br i1 %tmp1, label %bb, label %return
diff --git a/test/CodeGen/X86/subreg-to-reg-5.ll b/test/CodeGen/X86/subreg-to-reg-5.ll
deleted file mode 100644
index ba4c307..0000000
--- a/test/CodeGen/X86/subreg-to-reg-5.ll
+++ /dev/null
@@ -1,35 +0,0 @@
-; RUN: llc < %s -march=x86-64 > %t
-; RUN: grep addl %t
-; RUN: not egrep {movl|movq} %t
-
-define float @foo(float* %B) nounwind {
-entry:
- br label %bb2
-
-bb2: ; preds = %bb3, %entry
- %B_addr.0.rec = phi i64 [ %indvar.next154, %bb3 ], [ 0, %entry ] ; <i64> [#uses=2]
- %z = icmp slt i64 %B_addr.0.rec, 20000
- br i1 %z, label %bb3, label %bb4
-
-bb3: ; preds = %bb2
- %indvar.next154 = add i64 %B_addr.0.rec, 1 ; <i64> [#uses=1]
- br label %bb2
-
-bb4: ; preds = %bb2
- %B_addr.0 = getelementptr float* %B, i64 %B_addr.0.rec ; <float*> [#uses=1]
- %t1 = ptrtoint float* %B_addr.0 to i64 ; <i64> [#uses=1]
- %t2 = and i64 %t1, 4294967295 ; <i64> [#uses=1]
- %t3 = icmp eq i64 %t2, 0 ; <i1> [#uses=1]
- br i1 %t3, label %bb5, label %bb10.preheader
-
-bb10.preheader: ; preds = %bb4
- br label %bb9
-
-bb5: ; preds = %bb4
- ret float 7.0
-
-bb9: ; preds = %bb10.preheader
- %t5 = getelementptr float* %B, i64 0 ; <float*> [#uses=1]
- %t7 = load float* %t5 ; <float> [#uses=1]
- ret float %t7
-}
diff --git a/test/CodeGen/X86/tail-opts.ll b/test/CodeGen/X86/tail-opts.ll
index c5dbb04..7b21e1b 100644
--- a/test/CodeGen/X86/tail-opts.ll
+++ b/test/CodeGen/X86/tail-opts.ll
@@ -109,15 +109,15 @@ altret:
; CHECK: dont_merge_oddly:
; CHECK-NOT: ret
-; CHECK: ucomiss %xmm0, %xmm1
+; CHECK: ucomiss %xmm1, %xmm2
; CHECK-NEXT: jbe .LBB3_3
-; CHECK-NEXT: ucomiss %xmm2, %xmm0
+; CHECK-NEXT: ucomiss %xmm0, %xmm1
; CHECK-NEXT: ja .LBB3_4
; CHECK-NEXT: .LBB3_2:
; CHECK-NEXT: movb $1, %al
; CHECK-NEXT: ret
; CHECK-NEXT: .LBB3_3:
-; CHECK-NEXT: ucomiss %xmm2, %xmm1
+; CHECK-NEXT: ucomiss %xmm0, %xmm2
; CHECK-NEXT: jbe .LBB3_2
; CHECK-NEXT: .LBB3_4:
; CHECK-NEXT: xorb %al, %al
diff --git a/test/CodeGen/X86/unaligned-load.ll b/test/CodeGen/X86/unaligned-load.ll
index 7778983..b61803d 100644
--- a/test/CodeGen/X86/unaligned-load.ll
+++ b/test/CodeGen/X86/unaligned-load.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=x86_64-apple-darwin10.0 -relocation-model=dynamic-no-pic | FileCheck %s
+; RUN: llc < %s -mtriple=x86_64-apple-darwin10.0 -relocation-model=dynamic-no-pic --asm-verbose=0 | FileCheck %s
@.str1 = internal constant [31 x i8] c"DHRYSTONE PROGRAM, SOME STRING\00", align 8
@.str3 = internal constant [31 x i8] c"DHRYSTONE PROGRAM, 2'ND STRING\00", align 8
@@ -23,5 +23,5 @@ declare void @llvm.memcpy.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind
; CHECK: .align 3
; CHECK-NEXT: _.str1:
; CHECK-NEXT: .asciz "DHRYSTONE PROGRAM, SOME STRING"
-; CHECK-NEXT: .align 3
+; CHECK: .align 3
; CHECK-NEXT: _.str3:
diff --git a/test/CodeGen/X86/xor.ll b/test/CodeGen/X86/xor.ll
index 7bd06bb..9bfff8a 100644
--- a/test/CodeGen/X86/xor.ll
+++ b/test/CodeGen/X86/xor.ll
@@ -131,3 +131,14 @@ bb12:
; X32: andl {{.*}}[[REG]]
}
+define i32 @test8(i32 %a) nounwind {
+; rdar://7553032
+entry:
+ %t1 = sub i32 0, %a
+ %t2 = add i32 %t1, -1
+ ret i32 %t2
+; X64: test8:
+; X64: notl %eax
+; X32: test8:
+; X32: notl %eax
+}
diff --git a/test/DebugInfo/2010-01-19-DbgScope.ll b/test/DebugInfo/2010-01-19-DbgScope.ll
new file mode 100644
index 0000000..7afb5a5
--- /dev/null
+++ b/test/DebugInfo/2010-01-19-DbgScope.ll
@@ -0,0 +1,28 @@
+; RUN: llc -O0 < %s -o /dev/null
+; Ignore unreachable scopes.
+declare void @foo(i32) noreturn
+
+define i32 @bar() nounwind ssp {
+entry:
+ br i1 undef, label %bb, label %bb11, !dbg !0
+
+bb: ; preds = %entry
+ call void @foo(i32 0) noreturn nounwind, !dbg !7
+ unreachable, !dbg !7
+
+bb11: ; preds = %entry
+ ret i32 1, !dbg !11
+}
+
+!0 = metadata !{i32 8647, i32 0, metadata !1, null}
+!1 = metadata !{i32 458763, metadata !2} ; [ DW_TAG_lexical_block ]
+!2 = metadata !{i32 458798, i32 0, metadata !3, metadata !"bar", metadata !"bar", metadata !"bar", metadata !3, i32 8639, metadata !4, i1 true, i1 true, i32 0, i32 0, null} ; [ DW_TAG_subprogram ]
+!3 = metadata !{i32 458769, i32 0, i32 1, metadata !"c-parser.c", metadata !"llvmgcc", metadata !"LLVM build 00", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
+!4 = metadata !{i32 458773, metadata !3, metadata !"", metadata !3, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0} ; [ DW_TAG_subroutine_type ]
+!5 = metadata !{metadata !6}
+!6 = metadata !{i32 458788, metadata !3, metadata !"char", metadata !3, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ]
+!7 = metadata !{i32 8648, i32 0, metadata !8, null}
+!8 = metadata !{i32 458763, metadata !9} ; [ DW_TAG_lexical_block ]
+!9 = metadata !{i32 458763, metadata !10} ; [ DW_TAG_lexical_block ]
+!10 = metadata !{i32 458798, i32 0, metadata !3, metadata !"bar2", metadata !"bar2", metadata !"bar2", metadata !3, i32 8639, metadata !4, i1 true, i1 true, i32 0, i32 0, null} ; [ DW_TAG_subprogram ]
+!11 = metadata !{i32 8652, i32 0, metadata !1, null}
diff --git a/test/FrontendC/2010-01-18-Inlined-Debug.c b/test/FrontendC/2010-01-18-Inlined-Debug.c
new file mode 100644
index 0000000..4aec7b2
--- /dev/null
+++ b/test/FrontendC/2010-01-18-Inlined-Debug.c
@@ -0,0 +1,12 @@
+// PR: 6058
+// RUN: %llvmgcc -g -S %s -o - | llc -O0 -o /dev/null
+
+static inline int foo(double) __attribute__ ((always_inline));
+static inline int foo(double __x) { return __x; }
+
+void bar(double x) {
+ foo(x);
+}
+
+
+
diff --git a/test/FrontendC/pr5406.c b/test/FrontendC/pr5406.c
new file mode 100644
index 0000000..c873e51
--- /dev/null
+++ b/test/FrontendC/pr5406.c
@@ -0,0 +1,20 @@
+// RUN: %llvmgcc %s -S -emit-llvm -O0 -o - | FileCheck %s
+// PR 5406
+
+// XFAIL: *
+// XTARGET: arm
+
+typedef struct { char x[3]; } A0;
+void foo (int i, ...);
+
+
+// CHECK: call arm_aapcscc void (i32, ...)* @foo(i32 1, i32 {{.*}}) nounwind
+int main (void)
+{
+ A0 a3;
+ a3.x[0] = 0;
+ a3.x[0] = 0;
+ a3.x[2] = 26;
+ foo (1, a3 );
+ return 0;
+}
diff --git a/test/MC/AsmParser/X86/x86_instructions.s b/test/MC/AsmParser/X86/x86_instructions.s
index 4c5b698..ed806ee 100644
--- a/test/MC/AsmParser/X86/x86_instructions.s
+++ b/test/MC/AsmParser/X86/x86_instructions.s
@@ -16,7 +16,9 @@
movl %eax, 10(%ebp, %ebx, 4)
// CHECK: movl %eax, 10(,%ebx,4)
movl %eax, 10(, %ebx, 4)
-
+// CHECK: ret
+ ret
+
// FIXME: Check that this matches SUB32ri8
// CHECK: subl $1, %eax
subl $1, %eax
diff --git a/test/MC/AsmParser/directive_ascii.s b/test/MC/AsmParser/directive_ascii.s
index cc6d23b..5bfc1e9 100644
--- a/test/MC/AsmParser/directive_ascii.s
+++ b/test/MC/AsmParser/directive_ascii.s
@@ -23,27 +23,12 @@ TEST3:
.asciz "B", "C"
# CHECK: TEST4:
-# CHECK: .byte 1
-# CHECK: .byte 1
-# CHECK: .byte 7
-# CHECK: .byte 0
-# CHECK: .byte 56
-# CHECK: .byte 1
-# CHECK: .byte 0
-# CHECK: .byte 49
-# CHECK: .byte 128
-# CHECK: .byte 0
+# CHECK: .asciz "\001\001\007\0008\001\0001\200"
TEST4:
.ascii "\1\01\07\08\001\0001\200\0"
# CHECK: TEST5:
-# CHECK: .byte 8
-# CHECK: .byte 12
-# CHECK: .byte 10
-# CHECK: .byte 13
-# CHECK: .byte 9
-# CHECK: .byte 92
-# CHECK: .byte 34
+# CHECK: .ascii "\b\f\n\r\t\\\""
TEST5:
.ascii "\b\f\n\r\t\\\""
diff --git a/test/MC/AsmParser/directive_lcomm.s b/test/MC/AsmParser/directive_lcomm.s
index d38805f..0a0add5 100644
--- a/test/MC/AsmParser/directive_lcomm.s
+++ b/test/MC/AsmParser/directive_lcomm.s
@@ -1,4 +1,4 @@
-# RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
+# RUN: llvm-mc -triple i386-apple-darwin10 %s | FileCheck %s
# CHECK: TEST0:
# CHECK: .zerofill __DATA,__bss,a,7,4
diff --git a/test/MC/AsmParser/directive_space.s b/test/MC/AsmParser/directive_space.s
index a897654..e6353a4 100644
--- a/test/MC/AsmParser/directive_space.s
+++ b/test/MC/AsmParser/directive_space.s
@@ -1,12 +1,11 @@
-# RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
+# RUN: llvm-mc -triple i386-apple-darwin %s | FileCheck %s
# CHECK: TEST0:
-# CHECK: .byte 0
+# CHECK: .space 1
TEST0:
.space 1
# CHECK: TEST1:
-# CHECK: .byte 3
-# CHECK: .byte 3
+# CHECK: .space 2,3
TEST1:
.space 2, 3
diff --git a/test/Transforms/ConstProp/constant-expr.ll b/test/Transforms/ConstProp/constant-expr.ll
index eece37f..9963032 100644
--- a/test/Transforms/ConstProp/constant-expr.ll
+++ b/test/Transforms/ConstProp/constant-expr.ll
@@ -57,4 +57,11 @@
@T4 = global i1* inttoptr (i64 trunc (i256 lshr (i256 or (i256 and (i256 and (i256 shl (i256 zext (i64 ptrtoint (i1* @B to i64) to i256), i256 64), i256 -6277101735386680763495507056286727952638980837032266301441), i256 6277101735386680763835789423207666416102355444464034512895), i256 shl (i256 zext (i64 ptrtoint (i1* @A to i64) to i256), i256 192)), i256 64) to i64) to i1*)
; CHECK: @T5 = global i1* @A
-@T5 = global i1* inttoptr (i64 add (i64 trunc (i256 lshr (i256 or (i256 and (i256 and (i256 shl (i256 zext (i64 ptrtoint (i1* @B to i64) to i256), i256 64), i256 -6277101735386680763495507056286727952638980837032266301441), i256 6277101735386680763835789423207666416102355444464034512895), i256 shl (i256 zext (i64 ptrtoint (i1* @A to i64) to i256), i256 192)), i256 192) to i64), i64 trunc (i256 lshr (i256 or (i256 and (i256 and (i256 shl (i256 zext (i64 ptrtoint (i1* @B to i64) to i256), i256 64), i256 -6277101735386680763495507056286727952638980837032266301441), i256 6277101735386680763835789423207666416102355444464034512895), i256 shl (i256 zext (i64 ptrtoint (i1* @A to i64) to i256), i256 192)), i256 128) to i64)) to i1*) \ No newline at end of file
+@T5 = global i1* inttoptr (i64 add (i64 trunc (i256 lshr (i256 or (i256 and (i256 and (i256 shl (i256 zext (i64 ptrtoint (i1* @B to i64) to i256), i256 64), i256 -6277101735386680763495507056286727952638980837032266301441), i256 6277101735386680763835789423207666416102355444464034512895), i256 shl (i256 zext (i64 ptrtoint (i1* @A to i64) to i256), i256 192)), i256 192) to i64), i64 trunc (i256 lshr (i256 or (i256 and (i256 and (i256 shl (i256 zext (i64 ptrtoint (i1* @B to i64) to i256), i256 64), i256 -6277101735386680763495507056286727952638980837032266301441), i256 6277101735386680763835789423207666416102355444464034512895), i256 shl (i256 zext (i64 ptrtoint (i1* @A to i64) to i256), i256 192)), i256 128) to i64)) to i1*)
+
+
+
+; PR6096
+
+; No check line. This used to crash llvm-as.
+@T6 = global <2 x i1> fcmp ole (<2 x float> fdiv (<2 x float> undef, <2 x float> <float 1.000000e+00, float 1.000000e+00>), <2 x float> zeroinitializer)
diff --git a/test/Transforms/IndVarSimplify/gep-with-mul-base.ll b/test/Transforms/IndVarSimplify/gep-with-mul-base.ll
index 7809594..19d54ff 100644
--- a/test/Transforms/IndVarSimplify/gep-with-mul-base.ll
+++ b/test/Transforms/IndVarSimplify/gep-with-mul-base.ll
@@ -1,6 +1,7 @@
; RUN: opt < %s -indvars -S > %t
-; RUN: grep add %t | count 8
-; RUN: grep mul %t | count 7
+; RUN: grep add %t | count 6
+; RUN: grep sub %t | count 2
+; RUN: grep mul %t | count 6
define void @foo(i64 %n, i64 %m, i64 %o, double* nocapture %p) nounwind {
entry:
diff --git a/test/Transforms/InstCombine/apint-elim-logicalops.ll b/test/Transforms/InstCombine/apint-elim-logicalops.ll
deleted file mode 100644
index ec60e45..0000000
--- a/test/Transforms/InstCombine/apint-elim-logicalops.ll
+++ /dev/null
@@ -1,39 +0,0 @@
-; Test that elimination of logical operators works with
-; arbitrary precision integers.
-; RUN: opt < %s -instcombine -S | \
-; RUN: not grep {(and\|xor\|add\|shl\|shr)}
-; END.
-
-define i33 @test1(i33 %x) {
- %tmp.1 = and i33 %x, 65535 ; <i33> [#uses=1]
- %tmp.2 = xor i33 %tmp.1, -32768 ; <i33> [#uses=1]
- %tmp.3 = add i33 %tmp.2, 32768 ; <i33> [#uses=1]
- ret i33 %tmp.3
-}
-
-define i33 @test2(i33 %x) {
- %tmp.1 = and i33 %x, 65535 ; <i33> [#uses=1]
- %tmp.2 = xor i33 %tmp.1, 32768 ; <i33> [#uses=1]
- %tmp.3 = add i33 %tmp.2, -32768 ; <i33> [#uses=1]
- ret i33 %tmp.3
-}
-
-define i33 @test3(i16 %P) {
- %tmp.1 = zext i16 %P to i33 ; <i33> [#uses=1]
- %tmp.4 = xor i33 %tmp.1, 32768 ; <i33> [#uses=1]
- %tmp.5 = add i33 %tmp.4, -32768 ; <i33> [#uses=1]
- ret i33 %tmp.5
-}
-
-define i33 @test5(i33 %x) {
- %tmp.1 = and i33 %x, 254
- %tmp.2 = xor i33 %tmp.1, 128
- %tmp.3 = add i33 %tmp.2, -128
- ret i33 %tmp.3
-}
-
-define i33 @test6(i33 %x) {
- %tmp.2 = shl i33 %x, 16 ; <i33> [#uses=1]
- %tmp.4 = lshr i33 %tmp.2, 16 ; <i33> [#uses=1]
- ret i33 %tmp.4
-}
diff --git a/test/Transforms/InstCombine/bitcast-sext-vector.ll b/test/Transforms/InstCombine/bitcast-sext-vector.ll
new file mode 100644
index 0000000..d70bdba
--- /dev/null
+++ b/test/Transforms/InstCombine/bitcast-sext-vector.ll
@@ -0,0 +1,11 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+; CHECK: sext
+; Don't fold zero/sign extensions with a bitcast between a vector and scalar.
+
+define i32 @t(<4 x i8> %src1, <4 x i8> %src2) nounwind readonly {
+entry:
+ %cmp = icmp eq <4 x i8> %src1, %src2; <<4 x i1>> [#uses=1]
+ %sext = sext <4 x i1> %cmp to <4 x i8>
+ %val = bitcast <4 x i8> %sext to i32
+ ret i32 %val
+}
diff --git a/test/Transforms/InstCombine/canonicalize_branch.ll b/test/Transforms/InstCombine/canonicalize_branch.ll
index 52aff3d..24090ab 100644
--- a/test/Transforms/InstCombine/canonicalize_branch.ll
+++ b/test/Transforms/InstCombine/canonicalize_branch.ll
@@ -1,36 +1,44 @@
-; RUN: opt < %s -instcombine -S | \
-; RUN: not grep {icmp ne\|icmp ule\|icmp uge}
+; RUN: opt < %s -instcombine -S | FileCheck %s
define i32 @test1(i32 %X, i32 %Y) {
- %C = icmp ne i32 %X, %Y ; <i1> [#uses=1]
+ %C = icmp ne i32 %X, %Y
br i1 %C, label %T, label %F
-T: ; preds = %0
- ret i32 12
+; CHECK: @test1
+; CHECK: %C = icmp eq i32 %X, %Y
+; CHECK: br i1 %C, label %F, label %T
-F: ; preds = %0
+T:
+ ret i32 12
+F:
ret i32 123
}
define i32 @test2(i32 %X, i32 %Y) {
- %C = icmp ule i32 %X, %Y ; <i1> [#uses=1]
+ %C = icmp ule i32 %X, %Y
br i1 %C, label %T, label %F
-T: ; preds = %0
- ret i32 12
+; CHECK: @test2
+; CHECK: %C = icmp ugt i32 %X, %Y
+; CHECK: br i1 %C, label %F, label %T
-F: ; preds = %0
+T:
+ ret i32 12
+F:
ret i32 123
}
define i32 @test3(i32 %X, i32 %Y) {
- %C = icmp uge i32 %X, %Y ; <i1> [#uses=1]
+ %C = icmp uge i32 %X, %Y
br i1 %C, label %T, label %F
-T: ; preds = %0
- ret i32 12
+; CHECK: @test3
+; CHECK: %C = icmp ult i32 %X, %Y
+; CHECK: br i1 %C, label %F, label %T
-F: ; preds = %0
+T:
+ ret i32 12
+F:
ret i32 123
}
diff --git a/test/Transforms/InstCombine/fsub-fadd.ll b/test/Transforms/InstCombine/fsub-fadd.ll
deleted file mode 100644
index f4cff88..0000000
--- a/test/Transforms/InstCombine/fsub-fadd.ll
+++ /dev/null
@@ -1,39 +0,0 @@
-; RUN: opt < %s -instcombine -S | FileCheck %s
-; <rdar://problem/7530098>
-
-define void @func(double* %rhi, double* %rlo, double %xh, double %xl, double %yh, double %yl) nounwind ssp {
-entry:
- %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- %tmp = fmul double %xh, 0x41A0000002000000 ; <double> [#uses=2]
- %tmp1 = fsub double %xh, %tmp ; <double> [#uses=1]
- %tmp2 = fadd double %tmp1, %tmp ; <double> [#uses=3]
- %tmp3 = fsub double %xh, %tmp2 ; <double> [#uses=2]
- %tmp4 = fmul double %yh, 0x41A0000002000000 ; <double> [#uses=2]
- %tmp5 = fsub double %yh, %tmp4 ; <double> [#uses=1]
- %tmp6 = fadd double %tmp5, %tmp4 ; <double> [#uses=3]
- %tmp7 = fsub double %yh, %tmp6 ; <double> [#uses=2]
- %tmp8 = fmul double %xh, %yh ; <double> [#uses=3]
- %tmp9 = fmul double %tmp2, %tmp6 ; <double> [#uses=1]
- %tmp10 = fsub double %tmp9, %tmp8 ; <double> [#uses=1]
- %tmp11 = fmul double %tmp2, %tmp7 ; <double> [#uses=1]
- %tmp12 = fadd double %tmp10, %tmp11 ; <double> [#uses=1]
- %tmp13 = fmul double %tmp3, %tmp6 ; <double> [#uses=1]
- %tmp14 = fadd double %tmp12, %tmp13 ; <double> [#uses=1]
- %tmp15 = fmul double %tmp3, %tmp7 ; <double> [#uses=1]
- %tmp16 = fadd double %tmp14, %tmp15 ; <double> [#uses=1]
- %tmp17 = fmul double %xh, %yl ; <double> [#uses=1]
- %tmp18 = fmul double %xl, %yh ; <double> [#uses=1]
- %tmp19 = fadd double %tmp17, %tmp18 ; <double> [#uses=1]
- %tmp20 = fadd double %tmp19, %tmp16 ; <double> [#uses=2]
- %tmp21 = fadd double %tmp8, %tmp20 ; <double> [#uses=1]
- store double %tmp21, double* %rhi, align 8
- %tmp22 = load double* %rhi, align 8 ; <double> [#uses=1]
- %tmp23 = fsub double %tmp8, %tmp22 ; <double> [#uses=1]
- %tmp24 = fadd double %tmp23, %tmp20 ; <double> [#uses=1]
-
-; CHECK: %tmp23 = fsub double %tmp8, %tmp21
-; CHECK: %tmp24 = fadd double %tmp23, %tmp20
-
- store double %tmp24, double* %rlo, align 8
- ret void
-}
diff --git a/test/Transforms/InstCombine/fsub-fsub.ll b/test/Transforms/InstCombine/fsub-fsub.ll
deleted file mode 100644
index 94ebf09..0000000
--- a/test/Transforms/InstCombine/fsub-fsub.ll
+++ /dev/null
@@ -1,8 +0,0 @@
-; RUN: opt < %s -instcombine -S | grep fsub | count 2
-; PR4374
-
-define float @func(float %a, float %b) nounwind {
- %tmp3 = fsub float %a, %b
- %tmp4 = fsub float -0.000000e+00, %tmp3
- ret float %tmp4
-}
diff --git a/test/Transforms/InstCombine/fsub.ll b/test/Transforms/InstCombine/fsub.ll
new file mode 100644
index 0000000..af2fadd
--- /dev/null
+++ b/test/Transforms/InstCombine/fsub.ll
@@ -0,0 +1,23 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+; PR4374
+define float @test1(float %a, float %b) nounwind {
+ %t1 = fsub float %a, %b
+ %t2 = fsub float -0.000000e+00, %t1
+
+; CHECK: %t1 = fsub float %a, %b
+; CHECK-NEXT: %t2 = fsub float -0.000000e+00, %t1
+
+ ret float %t2
+}
+
+; <rdar://problem/7530098>
+define double @test2(double %x, double %y) nounwind {
+ %t1 = fadd double %x, %y
+ %t2 = fsub double %x, %t1
+
+; CHECK: %t1 = fadd double %x, %y
+; CHECK-NEXT: %t2 = fsub double %x, %t1
+
+ ret double %t2
+}
diff --git a/test/Transforms/InstCombine/idioms.ll b/test/Transforms/InstCombine/idioms.ll
new file mode 100644
index 0000000..6b3567f
--- /dev/null
+++ b/test/Transforms/InstCombine/idioms.ll
@@ -0,0 +1,32 @@
+; RUN: opt -instcombine %s -S | FileCheck %s
+
+; Check that code corresponding to the following C function is
+; simplified into a single ASR operation:
+;
+; int test_asr(int a, int b) {
+; return a < 0 ? -(-a - 1 >> b) - 1 : a >> b;
+; }
+;
+define i32 @test_asr(i32 %a, i32 %b) {
+entry:
+ %c = icmp slt i32 %a, 0
+ br i1 %c, label %bb2, label %bb3
+
+bb2:
+ %t1 = sub i32 0, %a
+ %not = sub i32 %t1, 1
+ %d = ashr i32 %not, %b
+ %t2 = sub i32 0, %d
+ %not2 = sub i32 %t2, 1
+ br label %bb4
+bb3:
+ %e = ashr i32 %a, %b
+ br label %bb4
+bb4:
+ %f = phi i32 [ %not2, %bb2 ], [ %e, %bb3 ]
+ ret i32 %f
+; CHECK: @test_asr
+; CHECK: bb4:
+; CHECK: %f = ashr i32 %a, %b
+; CHECK: ret i32 %f
+}
diff --git a/test/Transforms/InstCombine/signext.ll b/test/Transforms/InstCombine/signext.ll
index 008662e..1c52b62 100644
--- a/test/Transforms/InstCombine/signext.ll
+++ b/test/Transforms/InstCombine/signext.ll
@@ -1,12 +1,16 @@
-; RUN: opt < %s -instcombine -S | \
-; RUN: not grep {(and\|xor\|add\|shl\|shr)}
-; END.
+; RUN: opt < %s -instcombine -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"
define i32 @test1(i32 %x) {
%tmp.1 = and i32 %x, 65535 ; <i32> [#uses=1]
%tmp.2 = xor i32 %tmp.1, -32768 ; <i32> [#uses=1]
%tmp.3 = add i32 %tmp.2, 32768 ; <i32> [#uses=1]
ret i32 %tmp.3
+; CHECK: @test1
+; CHECK: %sext1 = shl i32 %x, 16
+; CHECK: %tmp.3 = ashr i32 %sext1, 16
+; CHECK: ret i32 %tmp.3
}
define i32 @test2(i32 %x) {
@@ -14,6 +18,10 @@ define i32 @test2(i32 %x) {
%tmp.2 = xor i32 %tmp.1, 32768 ; <i32> [#uses=1]
%tmp.3 = add i32 %tmp.2, -32768 ; <i32> [#uses=1]
ret i32 %tmp.3
+; CHECK: @test2
+; CHECK: %sext1 = shl i32 %x, 16
+; CHECK: %tmp.3 = ashr i32 %sext1, 16
+; CHECK: ret i32 %tmp.3
}
define i32 @test3(i16 %P) {
@@ -21,6 +29,9 @@ define i32 @test3(i16 %P) {
%tmp.4 = xor i32 %tmp.1, 32768 ; <i32> [#uses=1]
%tmp.5 = add i32 %tmp.4, -32768 ; <i32> [#uses=1]
ret i32 %tmp.5
+; CHECK: @test3
+; CHECK: %tmp.5 = sext i16 %P to i32
+; CHECK: ret i32 %tmp.5
}
define i32 @test4(i16 %P) {
@@ -28,18 +39,38 @@ define i32 @test4(i16 %P) {
%tmp.4 = xor i32 %tmp.1, 32768 ; <i32> [#uses=1]
%tmp.5 = add i32 %tmp.4, -32768 ; <i32> [#uses=1]
ret i32 %tmp.5
+; CHECK: @test4
+; CHECK: %tmp.5 = sext i16 %P to i32
+; CHECK: ret i32 %tmp.5
}
define i32 @test5(i32 %x) {
- %tmp.1 = and i32 %x, 254 ; <i32> [#uses=1]
+ %tmp.1 = and i32 %x, 255 ; <i32> [#uses=1]
%tmp.2 = xor i32 %tmp.1, 128 ; <i32> [#uses=1]
%tmp.3 = add i32 %tmp.2, -128 ; <i32> [#uses=1]
ret i32 %tmp.3
+; CHECK: @test5
+; CHECK: %sext1 = shl i32 %x, 24
+; CHECK: %tmp.3 = ashr i32 %sext1, 24
+; CHECK: ret i32 %tmp.3
}
define i32 @test6(i32 %x) {
%tmp.2 = shl i32 %x, 16 ; <i32> [#uses=1]
%tmp.4 = ashr i32 %tmp.2, 16 ; <i32> [#uses=1]
ret i32 %tmp.4
+; CHECK: @test6
+; CHECK: %tmp.2 = shl i32 %x, 16
+; CHECK: %tmp.4 = ashr i32 %tmp.2, 16
+; CHECK: ret i32 %tmp.4
}
+define i32 @test7(i16 %P) {
+ %tmp.1 = zext i16 %P to i32 ; <i32> [#uses=1]
+ %sext1 = shl i32 %tmp.1, 16 ; <i32> [#uses=1]
+ %tmp.5 = ashr i32 %sext1, 16 ; <i32> [#uses=1]
+ ret i32 %tmp.5
+; CHECK: @test7
+; CHECK: %tmp.5 = sext i16 %P to i32
+; CHECK: ret i32 %tmp.5
+}
diff --git a/test/Transforms/InstCombine/xor2.ll b/test/Transforms/InstCombine/xor2.ll
index 23a9915..de3d65d 100644
--- a/test/Transforms/InstCombine/xor2.ll
+++ b/test/Transforms/InstCombine/xor2.ll
@@ -41,3 +41,13 @@ define i32 @test3(i32 %tmp1) {
%ov110 = xor i32 %ov31, 153
ret i32 %ov110
}
+
+define i32 @test4(i32 %A, i32 %B) {
+ %1 = xor i32 %A, -1
+ %2 = ashr i32 %1, %B
+ %3 = xor i32 %2, -1
+ ret i32 %3
+; CHECK: @test4
+; CHECK: %1 = ashr i32 %A, %B
+; CHECK: ret i32 %1
+}
diff --git a/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-0.ll b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-0.ll
index 56a89f6..36941ad 100644
--- a/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-0.ll
+++ b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-0.ll
@@ -6,7 +6,7 @@ target triple = "x86_64-apple-darwin9"
; happens before the relevant use, so the comparison stride can't be
; easily changed.
-define void @foo() {
+define void @foo() nounwind {
entry:
br label %loop
diff --git a/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll
index 8a3978b..ea8a259 100644
--- a/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll
+++ b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll
@@ -1,10 +1,10 @@
-; RUN: llc %s -o - --x86-asm-syntax=att | grep {cmpq \$8}
+; RUN: llc %s -o - --x86-asm-syntax=att | grep {cmp. \$8}
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"
target triple = "x86_64-apple-darwin9"
-; This is like change-compare-stride-trickiness-0.ll except the comparison
-; happens after the relevant use, so the comparison stride can be
-; easily changed.
+; The comparison happens after the relevant use, so the stride can easily
+; be changed. The comparison can be done in a narrower mode than the
+; induction variable.
define void @foo() nounwind {
entry:
diff --git a/test/Transforms/LoopStrengthReduce/icmp_use_postinc.ll b/test/Transforms/LoopStrengthReduce/icmp_use_postinc.ll
deleted file mode 100644
index 4ad5d14..0000000
--- a/test/Transforms/LoopStrengthReduce/icmp_use_postinc.ll
+++ /dev/null
@@ -1,27 +0,0 @@
-; RUN: opt < %s -loop-reduce -S | FileCheck %s
-
-define i32 @main(i32 %argc, i8** nocapture %argv) nounwind ssp {
-entry:
- br i1 undef, label %bb4.preheader, label %bb.nph8
-
-bb4.preheader: ; preds = %entry
- br label %bb4
-
-bb1: ; preds = %bb4
- br i1 undef, label %bb.nph8, label %bb3
-
-bb3: ; preds = %bb1
- %phitmp = add i32 %indvar, 1 ; <i32> [#uses=1]
- br label %bb4
-
-bb4: ; preds = %bb3, %bb4.preheader
-; CHECK: %lsr.iv = phi
-; CHECK: %lsr.iv.next = add i32 %lsr.iv, 1
-; CHECK: %0 = icmp slt i32 %lsr.iv.next, %argc
- %indvar = phi i32 [ 1, %bb4.preheader ], [ %phitmp, %bb3 ] ; <i32> [#uses=2]
- %0 = icmp slt i32 %indvar, %argc ; <i1> [#uses=1]
- br i1 %0, label %bb1, label %bb.nph8
-
-bb.nph8: ; preds = %bb4, %bb1, %entry
- unreachable
-}
diff --git a/test/Transforms/LoopStrengthReduce/related_indvars.ll b/test/Transforms/LoopStrengthReduce/related_indvars.ll
index 2494378..12942bf 100644
--- a/test/Transforms/LoopStrengthReduce/related_indvars.ll
+++ b/test/Transforms/LoopStrengthReduce/related_indvars.ll
@@ -7,7 +7,7 @@
; *D++ = F;
; }
-define void @foo(double* %D, double* %E, double %F) {
+define void @foo(double* %D, double* %E, double %F) nounwind {
entry:
%tmp.24 = icmp eq double* %D, %E ; <i1> [#uses=1]
br i1 %tmp.24, label %return, label %no_exit
diff --git a/test/Transforms/Mem2Reg/ConvertDebugInfo.ll b/test/Transforms/Mem2Reg/ConvertDebugInfo.ll
new file mode 100644
index 0000000..8e309c0
--- /dev/null
+++ b/test/Transforms/Mem2Reg/ConvertDebugInfo.ll
@@ -0,0 +1,31 @@
+; RUN: opt < %s -mem2reg -S | FileCheck %s
+
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+
+define double @testfunc(i32 %i, double %j) {
+ %I = alloca i32 ; <i32*> [#uses=4]
+ call void @llvm.dbg.declare(metadata !{i32* %I}, metadata !0)
+ %J = alloca double ; <double*> [#uses=2]
+ call void @llvm.dbg.declare(metadata !{double* %J}, metadata !1)
+; CHECK: call void @llvm.dbg.value(metadata !{i32 %i}, i64 0, metadata !0)
+ store i32 %i, i32* %I
+; CHECK: call void @llvm.dbg.value(metadata !{double %j}, i64 0, metadata !1)
+ store double %j, double* %J
+ %t1 = load i32* %I ; <i32> [#uses=1]
+ %t2 = add i32 %t1, 1 ; <i32> [#uses=1]
+ store i32 %t2, i32* %I
+ %t3 = load i32* %I ; <i32> [#uses=1]
+ %t4 = sitofp i32 %t3 to double ; <double> [#uses=1]
+ %t5 = load double* %J ; <double> [#uses=1]
+ %t6 = fmul double %t4, %t5 ; <double> [#uses=1]
+ ret double %t6
+}
+
+declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
+
+!bar = !{!0}
+!foo = !{!2}
+
+!0 = metadata !{i32 459008, metadata !1, metadata !"foo", metadata !2, i32 5, metadata !"foo"} ; [ DW_TAG_auto_variable ]
+!1 = metadata !{i32 459008, metadata !1, metadata !"foo", metadata !0, i32 5, metadata !1} ; [ DW_TAG_auto_variable ]
+!2 = metadata !{i32 458804, i32 0, metadata !2, metadata !"foo", metadata !"bar", metadata !"bar", metadata !2, i32 3, metadata !0, i1 false, i1 true} ; [ DW_TAG_variable ]
diff --git a/test/Transforms/Reassociate/inverses.ll b/test/Transforms/Reassociate/inverses.ll
index fa1a4bd..34abdc7 100644
--- a/test/Transforms/Reassociate/inverses.ll
+++ b/test/Transforms/Reassociate/inverses.ll
@@ -1,28 +1,34 @@
-; RUN: opt < %s -reassociate -dce -S | \
-; RUN: not grep {\\(and\\|sub\\)}
+; RUN: opt < %s -reassociate -die -S | FileCheck %s
define i32 @test1(i32 %a, i32 %b) {
- %tmp.2 = and i32 %b, %a ; <i32> [#uses=1]
- %tmp.4 = xor i32 %a, -1 ; <i32> [#uses=1]
+ %tmp.2 = and i32 %b, %a
+ %tmp.4 = xor i32 %a, -1
; (A&B)&~A == 0
- %tmp.5 = and i32 %tmp.2, %tmp.4 ; <i32> [#uses=1]
+ %tmp.5 = and i32 %tmp.2, %tmp.4
ret i32 %tmp.5
+; CHECK: @test1
+; CHECK: ret i32 0
}
define i32 @test2(i32 %a, i32 %b) {
- %tmp.1 = and i32 %a, 1234 ; <i32> [#uses=1]
- %tmp.2 = and i32 %b, %tmp.1 ; <i32> [#uses=1]
- %tmp.4 = xor i32 %a, -1 ; <i32> [#uses=1]
+ %tmp.1 = and i32 %a, 1234
+ %tmp.2 = and i32 %b, %tmp.1
+ %tmp.4 = xor i32 %a, -1
; A&~A == 0
- %tmp.5 = and i32 %tmp.2, %tmp.4 ; <i32> [#uses=1]
+ %tmp.5 = and i32 %tmp.2, %tmp.4
ret i32 %tmp.5
+; CHECK: @test2
+; CHECK: ret i32 0
}
define i32 @test3(i32 %b, i32 %a) {
- %tmp.1 = add i32 %a, 1234 ; <i32> [#uses=1]
- %tmp.2 = add i32 %b, %tmp.1 ; <i32> [#uses=1]
- %tmp.4 = sub i32 0, %a ; <i32> [#uses=1]
+ %tmp.1 = add i32 %a, 1234
+ %tmp.2 = add i32 %b, %tmp.1
+ %tmp.4 = sub i32 0, %a
; (b+(a+1234))+-a -> b+1234
- %tmp.5 = add i32 %tmp.2, %tmp.4 ; <i32> [#uses=1]
+ %tmp.5 = add i32 %tmp.2, %tmp.4
ret i32 %tmp.5
+; CHECK: @test3
+; CHECK: %tmp.5 = add i32 %b, 1234
+; CHECK: ret i32 %tmp.5
}
diff --git a/test/Transforms/ScalarRepl/2010-01-18-SelfCopy.ll b/test/Transforms/ScalarRepl/2010-01-18-SelfCopy.ll
new file mode 100644
index 0000000..74cf251
--- /dev/null
+++ b/test/Transforms/ScalarRepl/2010-01-18-SelfCopy.ll
@@ -0,0 +1,18 @@
+; RUN: opt < %s -scalarrepl -S | FileCheck %s
+; Radar 7552893
+
+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:128:128-n8:16:32"
+
+%struct.test = type { [3 x double ] }
+
+define arm_apcscc void @test_memcpy_self() nounwind {
+; CHECK: @test_memcpy_self
+; CHECK-NOT: alloca
+; CHECK: ret void
+ %1 = alloca %struct.test
+ %2 = bitcast %struct.test* %1 to i8*
+ call void @llvm.memcpy.i32(i8* %2, i8* %2, i32 24, i32 4)
+ ret void
+}
+
+declare void @llvm.memcpy.i32(i8* nocapture, i8* nocapture, i32, i32) nounwind
diff --git a/test/lit.cfg b/test/lit.cfg
index 246f270..8e85168 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -133,7 +133,7 @@ def llvm_gcc_supports(name):
bindings = set(site_exp['llvm_bindings'].split(','))
def llvm_supports_binding(name):
- return name in langs
+ return name in bindings
# Provide on_clone hook for reading 'dg.exp'.
import os
diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp
index a591417..c2b002f 100644
--- a/tools/bugpoint/Miscompilation.cpp
+++ b/tools/bugpoint/Miscompilation.cpp
@@ -22,7 +22,6 @@
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/Analysis/Verifier.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileUtilities.h"
@@ -235,30 +234,16 @@ bool ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function*>&Funcs){
return TestFn(BD, ToOptimize, ToNotOptimize);
}
-/// DisambiguateGlobalSymbols - Mangle symbols to guarantee uniqueness by
-/// modifying predominantly internal symbols rather than external ones.
+/// DisambiguateGlobalSymbols - Give anonymous global values names.
///
static void DisambiguateGlobalSymbols(Module *M) {
- // Try not to cause collisions by minimizing chances of renaming an
- // already-external symbol, so take in external globals and functions as-is.
- // The code should work correctly without disambiguation (assuming the same
- // mangler is used by the two code generators), but having symbols with the
- // same name causes warnings to be emitted by the code generator.
- Mangler Mang(*M);
- // Agree with the CBE on symbol naming
- Mang.markCharUnacceptable('.');
for (Module::global_iterator I = M->global_begin(), E = M->global_end();
- I != E; ++I) {
- // Don't mangle asm names.
- if (!I->hasName() || I->getName()[0] != 1)
- I->setName(Mang.getMangledName(I));
- }
- for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
- // Don't mangle asm names or intrinsics.
- if ((!I->hasName() || I->getName()[0] != 1) &&
- I->getIntrinsicID() == 0)
- I->setName(Mang.getMangledName(I));
- }
+ I != E; ++I)
+ if (!I->hasName())
+ I->setName("anon_global");
+ for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
+ if (!I->hasName())
+ I->setName("anon_fn");
}
/// ExtractLoops - Given a reduced list of functions that still exposed the bug,
@@ -548,10 +533,6 @@ DebugAMiscompilation(BugDriver &BD,
ExtractLoops(BD, TestFn, MiscompiledFunctions)) {
// Okay, we extracted some loops and the problem still appears. See if we
// can eliminate some of the created functions from being candidates.
-
- // Loop extraction can introduce functions with the same name (foo_code).
- // Make sure to disambiguate the symbols so that when the program is split
- // apart that we can link it back together again.
DisambiguateGlobalSymbols(BD.getProgram());
// Do the reduction...
@@ -569,10 +550,6 @@ DebugAMiscompilation(BugDriver &BD,
ExtractBlocks(BD, TestFn, MiscompiledFunctions)) {
// Okay, we extracted some blocks and the problem still appears. See if we
// can eliminate some of the created functions from being candidates.
-
- // Block extraction can introduce functions with the same name (foo_code).
- // Make sure to disambiguate the symbols so that when the program is split
- // apart that we can link it back together again.
DisambiguateGlobalSymbols(BD.getProgram());
// Do the reduction...
diff --git a/tools/gold/Makefile b/tools/gold/Makefile
index 7bac4ec..3f77229 100644
--- a/tools/gold/Makefile
+++ b/tools/gold/Makefile
@@ -19,6 +19,7 @@ LINK_LIBS_IN_SHARED=1
SHARED_LIBRARY = 1
BUILD_ARCHIVE = 0
LOADABLE_MODULE = 1
+CXXFLAGS = -fno-rtti
LINK_COMPONENTS := support system
LIBS += -llto
diff --git a/tools/llc/Makefile b/tools/llc/Makefile
index 7319aad..6b5b125 100644
--- a/tools/llc/Makefile
+++ b/tools/llc/Makefile
@@ -9,6 +9,7 @@
LEVEL = ../..
TOOLNAME = llc
+CXXFLAGS = -fno-rtti
# Include this here so we can get the configuration of the targets
# that have been configured for construction. We have to do this
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
index 930de26..4f93a43 100644
--- a/tools/llc/llc.cpp
+++ b/tools/llc/llc.cpp
@@ -366,9 +366,7 @@ int main(int argc, char **argv) {
sys::Path(OutputFilename).eraseFromDisk();
return 1;
case FileModel::AsmFile:
- break;
case FileModel::MachOFile:
- OCE = AddMachOWriter(Passes, *Out, Target);
break;
case FileModel::ElfFile:
OCE = AddELFWriter(Passes, *Out, Target);
diff --git a/tools/lli/Makefile b/tools/lli/Makefile
index 8f6eeed..2341bed 100644
--- a/tools/lli/Makefile
+++ b/tools/lli/Makefile
@@ -9,6 +9,7 @@
LEVEL := ../..
TOOLNAME := lli
+CXXFLAGS = -fno-rtti
LINK_COMPONENTS := jit interpreter nativecodegen bitreader selectiondag
# Enable JIT support
diff --git a/tools/llvm-ar/Makefile b/tools/llvm-ar/Makefile
index e4fe4e8..3db7964 100644
--- a/tools/llvm-ar/Makefile
+++ b/tools/llvm-ar/Makefile
@@ -11,6 +11,7 @@ LEVEL = ../..
TOOLNAME = llvm-ar
LINK_COMPONENTS = archive
REQUIRES_EH := 1
+#CXXFLAGS = -fno-rtti
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
diff --git a/tools/llvm-as/Makefile b/tools/llvm-as/Makefile
index ae449c4..d6fbd71 100644
--- a/tools/llvm-as/Makefile
+++ b/tools/llvm-as/Makefile
@@ -10,7 +10,7 @@
LEVEL = ../..
TOOLNAME = llvm-as
LINK_COMPONENTS := asmparser bitwriter
-REQUIRES_EH := 1
+CXXFLAGS = -fno-rtti
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
diff --git a/tools/llvm-bcanalyzer/Makefile b/tools/llvm-bcanalyzer/Makefile
index 251f758..488387d 100644
--- a/tools/llvm-bcanalyzer/Makefile
+++ b/tools/llvm-bcanalyzer/Makefile
@@ -10,7 +10,6 @@ LEVEL = ../..
TOOLNAME = llvm-bcanalyzer
LINK_COMPONENTS := bitreader
-REQUIRES_EH := 1
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
diff --git a/tools/llvm-config/Makefile b/tools/llvm-config/Makefile
index 6eedca0..e5bdc04 100644
--- a/tools/llvm-config/Makefile
+++ b/tools/llvm-config/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../..
EXTRA_DIST = LibDeps.txt FinalLibDeps.txt llvm-config.in.in find-cycles.pl
-REQUIRES_EH := 1
include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-config/llvm-config.in.in b/tools/llvm-config/llvm-config.in.in
index d0edda0..d435d57 100644
--- a/tools/llvm-config/llvm-config.in.in
+++ b/tools/llvm-config/llvm-config.in.in
@@ -18,6 +18,7 @@
use 5.006;
use strict;
use warnings;
+use Cwd 'abs_path';
#---- begin autoconf values ----
my $PACKAGE_NAME = q{@PACKAGE_NAME@};
@@ -53,20 +54,14 @@ my $LLVM_BUILDMODE = q{@LLVM_BUILDMODE@};
# Convert the current executable name into its directory (e.g. ".").
my ($RUN_DIR) = ($0 =~ /^(.*)\/.*$/);
-# Find the unix pwd program: we don't want to use the bash builtin, as it does
-# not look through symlinks etc.
-my $PWD = `which pwd`;
-chomp($PWD);
-$PWD = "pwd" if (!-e $PWD);
-
# Turn the directory into an absolute directory on the file system, also pop up
# from "bin" into the build or prefix dir.
-my $ABS_RUN_DIR = `cd $RUN_DIR/..; $PWD`;
+my $ABS_RUN_DIR = abs_path("$RUN_DIR/..");
chomp($ABS_RUN_DIR);
# Compute the absolute object directory build, e.g. "foo/llvm/Debug".
my $ABS_OBJ_ROOT = "$LLVM_OBJ_ROOT/$LLVM_BUILDMODE";
-$ABS_OBJ_ROOT = `cd $ABS_OBJ_ROOT; $PWD` if (-d $ABS_OBJ_ROOT);
+$ABS_OBJ_ROOT = abs_path("$ABS_OBJ_ROOT") if (-d $ABS_OBJ_ROOT);
chomp($ABS_OBJ_ROOT);
my $INCLUDEDIR = "$ABS_RUN_DIR/include";
@@ -134,9 +129,9 @@ foreach my $arg (@ARGV) {
} elsif ($arg eq "--build-mode") {
$has_opt = 1; print "$LLVM_BUILDMODE\n";
} elsif ($arg eq "--obj-root") {
- $has_opt = 1; print `cd $LLVM_OBJ_ROOT/; $PWD`;
+ $has_opt = 1; print abs_path("$LLVM_OBJ_ROOT/");
} elsif ($arg eq "--src-root") {
- $has_opt = 1; print `cd $LLVM_SRC_ROOT/; $PWD`;
+ $has_opt = 1; print abs_path("$LLVM_SRC_ROOT/");
} else {
usage();
}
diff --git a/tools/llvm-dis/Makefile b/tools/llvm-dis/Makefile
index dfd5e34..96f3cbb 100644
--- a/tools/llvm-dis/Makefile
+++ b/tools/llvm-dis/Makefile
@@ -10,7 +10,7 @@ LEVEL = ../..
TOOLNAME = llvm-dis
LINK_COMPONENTS := bitreader
-REQUIRES_EH := 1
+CXXFLAGS = -fno-rtti
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
diff --git a/tools/llvm-extract/Makefile b/tools/llvm-extract/Makefile
index 5672aa3..dee0572 100644
--- a/tools/llvm-extract/Makefile
+++ b/tools/llvm-extract/Makefile
@@ -11,6 +11,7 @@ LEVEL = ../..
TOOLNAME = llvm-extract
LINK_COMPONENTS := ipo bitreader bitwriter asmparser
+CXXFLAGS = -fno-rtti
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
diff --git a/tools/llvm-ld/Makefile b/tools/llvm-ld/Makefile
index 1ef9bf1..1da1966 100644
--- a/tools/llvm-ld/Makefile
+++ b/tools/llvm-ld/Makefile
@@ -11,5 +11,6 @@ LEVEL = ../..
TOOLNAME = llvm-ld
LINK_COMPONENTS = ipo scalaropts linker archive bitwriter
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-link/Makefile b/tools/llvm-link/Makefile
index 2637018..de592aa 100644
--- a/tools/llvm-link/Makefile
+++ b/tools/llvm-link/Makefile
@@ -10,6 +10,7 @@ LEVEL = ../..
TOOLNAME = llvm-link
LINK_COMPONENTS = linker bitreader bitwriter asmparser
+CXXFLAGS = -fno-rtti
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
diff --git a/tools/llvm-mc/AsmLexer.cpp b/tools/llvm-mc/AsmLexer.cpp
index ba0d247..234b8f3 100644
--- a/tools/llvm-mc/AsmLexer.cpp
+++ b/tools/llvm-mc/AsmLexer.cpp
@@ -12,7 +12,7 @@
//===----------------------------------------------------------------------===//
#include "AsmLexer.h"
-#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/SMLoc.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Config/config.h" // for strtoull.
#include "llvm/MC/MCAsmInfo.h"
@@ -21,78 +21,53 @@
#include <cstdlib>
using namespace llvm;
-AsmLexer::AsmLexer(SourceMgr &SM, const MCAsmInfo &_MAI) : SrcMgr(SM),
- MAI(_MAI) {
- CurBuffer = 0;
- CurBuf = SrcMgr.getMemoryBuffer(CurBuffer);
- CurPtr = CurBuf->getBufferStart();
+AsmLexer::AsmLexer(const MCAsmInfo &_MAI) : MAI(_MAI) {
+ CurBuf = NULL;
+ CurPtr = NULL;
TokStart = 0;
}
AsmLexer::~AsmLexer() {
}
-SMLoc AsmLexer::getLoc() const {
- return SMLoc::getFromPointer(TokStart);
+void AsmLexer::setBuffer(const MemoryBuffer *buf, const char *ptr) {
+ CurBuf = buf;
+
+ if (ptr)
+ CurPtr = ptr;
+ else
+ CurPtr = CurBuf->getBufferStart();
+
+ TokStart = 0;
}
-void AsmLexer::PrintMessage(SMLoc Loc, const std::string &Msg,
- const char *Type) const {
- SrcMgr.PrintMessage(Loc, Msg, Type);
+SMLoc AsmLexer::getLoc() const {
+ return SMLoc::getFromPointer(TokStart);
}
/// ReturnError - Set the error to the specified string at the specified
/// location. This is defined to always return AsmToken::Error.
AsmToken AsmLexer::ReturnError(const char *Loc, const std::string &Msg) {
- PrintMessage(SMLoc::getFromPointer(Loc), Msg, "error");
- return AsmToken(AsmToken::Error, StringRef(Loc, 0));
-}
-
-/// EnterIncludeFile - Enter the specified file. This prints an error and
-/// returns true on failure.
-bool AsmLexer::EnterIncludeFile(const std::string &Filename) {
- int NewBuf = SrcMgr.AddIncludeFile(Filename, SMLoc::getFromPointer(CurPtr));
- if (NewBuf == -1)
- return true;
+ SetError(SMLoc::getFromPointer(Loc), Msg);
- // Save the line number and lex buffer of the includer.
- CurBuffer = NewBuf;
- CurBuf = SrcMgr.getMemoryBuffer(CurBuffer);
- CurPtr = CurBuf->getBufferStart();
- return false;
+ return AsmToken(AsmToken::Error, StringRef(Loc, 0));
}
-
int AsmLexer::getNextChar() {
char CurChar = *CurPtr++;
switch (CurChar) {
default:
return (unsigned char)CurChar;
- case 0: {
+ case 0:
// A nul character in the stream is either the end of the current buffer or
// a random nul in the file. Disambiguate that here.
if (CurPtr-1 != CurBuf->getBufferEnd())
return 0; // Just whitespace.
- // If this is the end of an included file, pop the parent file off the
- // include stack.
- SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
- if (ParentIncludeLoc != SMLoc()) {
- CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc);
- CurBuf = SrcMgr.getMemoryBuffer(CurBuffer);
- CurPtr = ParentIncludeLoc.getPointer();
-
- // Reset the token start pointer to the start of the new file.
- TokStart = CurPtr;
-
- return getNextChar();
- }
-
// Otherwise, return end of file.
--CurPtr; // Another call to lex will return EOF again.
return EOF;
}
- }
}
/// LexIdentifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
diff --git a/tools/llvm-mc/AsmLexer.h b/tools/llvm-mc/AsmLexer.h
index ce292f6..1d49e4b 100644
--- a/tools/llvm-mc/AsmLexer.h
+++ b/tools/llvm-mc/AsmLexer.h
@@ -23,23 +23,17 @@
namespace llvm {
class MemoryBuffer;
-class SourceMgr;
class SMLoc;
class MCAsmInfo;
/// AsmLexer - Lexer class for assembly files.
class AsmLexer : public MCAsmLexer {
- SourceMgr &SrcMgr;
const MCAsmInfo &MAI;
const char *CurPtr;
const MemoryBuffer *CurBuf;
const char *TokStart;
-
- /// This is the current buffer index we're lexing from as managed by the
- /// SourceMgr object.
- int CurBuffer;
void operator=(const AsmLexer&); // DO NOT IMPLEMENT
AsmLexer(const AsmLexer&); // DO NOT IMPLEMENT
@@ -49,20 +43,19 @@ protected:
virtual AsmToken LexToken();
public:
- AsmLexer(SourceMgr &SrcMgr, const MCAsmInfo &MAI);
+ AsmLexer(const MCAsmInfo &MAI);
~AsmLexer();
+ void setBuffer(const MemoryBuffer *buf, const char *ptr = NULL);
+
SMLoc getLoc() const;
StringRef LexUntilEndOfStatement();
bool isAtStartOfComment(char Char);
-
- /// EnterIncludeFile - Enter the specified file. This returns true on failure.
- bool EnterIncludeFile(const std::string &Filename);
-
- void PrintMessage(SMLoc Loc, const std::string &Msg, const char *Type) const;
+ const MCAsmInfo &getMAI() const { return MAI; }
+
private:
int getNextChar();
AsmToken ReturnError(const char *Loc, const std::string &Msg);
diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp
index 2eb75a7..068e506 100644
--- a/tools/llvm-mc/AsmParser.cpp
+++ b/tools/llvm-mc/AsmParser.cpp
@@ -29,10 +29,8 @@
#include "llvm/Target/TargetAsmParser.h"
using namespace llvm;
-/// getStartLoc - Get the location of the first token of this operand.
-SMLoc MCParsedAsmOperand::getStartLoc() const { return SMLoc(); }
-SMLoc MCParsedAsmOperand::getEndLoc() const { return SMLoc(); }
+enum { DEFAULT_ADDRSPACE = 0 };
// Mach-O section uniquing.
//
@@ -42,8 +40,10 @@ typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out,
const MCAsmInfo &_MAI)
- : Lexer(_SM, _MAI), Ctx(_Ctx), Out(_Out), TargetParser(0),
- SectionUniquingMap(0) {
+ : Lexer(_MAI), Ctx(_Ctx), Out(_Out), SrcMgr(_SM), TargetParser(0),
+ CurBuffer(0), SectionUniquingMap(0) {
+ Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
+
// Debugging directives.
AddDirectiveHandler(".file", &AsmParser::ParseDirectiveFile);
AddDirectiveHandler(".line", &AsmParser::ParseDirectiveLine);
@@ -89,19 +89,57 @@ const MCSection *AsmParser::getMachOSection(const StringRef &Segment,
}
void AsmParser::Warning(SMLoc L, const Twine &Msg) {
- Lexer.PrintMessage(L, Msg.str(), "warning");
+ PrintMessage(L, Msg.str(), "warning");
}
bool AsmParser::Error(SMLoc L, const Twine &Msg) {
- Lexer.PrintMessage(L, Msg.str(), "error");
+ PrintMessage(L, Msg.str(), "error");
return true;
}
bool AsmParser::TokError(const char *Msg) {
- Lexer.PrintMessage(Lexer.getLoc(), Msg, "error");
+ PrintMessage(Lexer.getLoc(), Msg, "error");
return true;
}
+void AsmParser::PrintMessage(SMLoc Loc, const std::string &Msg,
+ const char *Type) const {
+ SrcMgr.PrintMessage(Loc, Msg, Type);
+}
+
+bool AsmParser::EnterIncludeFile(const std::string &Filename) {
+ int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc());
+ if (NewBuf == -1)
+ return true;
+
+ CurBuffer = NewBuf;
+
+ Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
+
+ return false;
+}
+
+const AsmToken &AsmParser::Lex() {
+ const AsmToken *tok = &Lexer.Lex();
+
+ if (tok->is(AsmToken::Eof)) {
+ // If this is the end of an included file, pop the parent file off the
+ // include stack.
+ SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
+ if (ParentIncludeLoc != SMLoc()) {
+ CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc);
+ Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer),
+ ParentIncludeLoc.getPointer());
+ tok = &Lexer.Lex();
+ }
+ }
+
+ if (tok->is(AsmToken::Error))
+ PrintMessage(Lexer.getErrLoc(), Lexer.getErr(), "error");
+
+ return *tok;
+}
+
bool AsmParser::Run() {
// Create the initial section.
//
@@ -113,7 +151,7 @@ bool AsmParser::Run() {
// Prime the lexer.
- Lexer.Lex();
+ Lex();
bool HadError = false;
@@ -124,7 +162,7 @@ bool AsmParser::Run() {
// Handle conditional assembly here before calling ParseStatement()
if (Lexer.getKind() == AsmToken::Identifier) {
// If we have an identifier, handle it as the key symbol.
- AsmToken ID = Lexer.getTok();
+ AsmToken ID = getTok();
SMLoc IDLoc = ID.getLoc();
StringRef IDVal = ID.getString();
@@ -180,11 +218,11 @@ bool AsmParser::ParseConditionalAssemblyDirectives(StringRef Directive,
void AsmParser::EatToEndOfStatement() {
while (Lexer.isNot(AsmToken::EndOfStatement) &&
Lexer.isNot(AsmToken::Eof))
- Lexer.Lex();
+ Lex();
// Eat EOL.
if (Lexer.is(AsmToken::EndOfStatement))
- Lexer.Lex();
+ Lex();
}
@@ -193,11 +231,12 @@ void AsmParser::EatToEndOfStatement() {
///
/// parenexpr ::= expr)
///
-bool AsmParser::ParseParenExpr(const MCExpr *&Res) {
+bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
if (ParseExpression(Res)) return true;
if (Lexer.isNot(AsmToken::RParen))
return TokError("expected ')' in parentheses expression");
- Lexer.Lex();
+ EndLoc = Lexer.getLoc();
+ Lex();
return false;
}
@@ -217,21 +256,22 @@ MCSymbol *AsmParser::CreateSymbol(StringRef Name) {
/// primaryexpr ::= symbol
/// primaryexpr ::= number
/// primaryexpr ::= ~,+,- primaryexpr
-bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res) {
+bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
switch (Lexer.getKind()) {
default:
return TokError("unknown token in expression");
case AsmToken::Exclaim:
- Lexer.Lex(); // Eat the operator.
- if (ParsePrimaryExpr(Res))
+ Lex(); // Eat the operator.
+ if (ParsePrimaryExpr(Res, EndLoc))
return true;
Res = MCUnaryExpr::CreateLNot(Res, getContext());
return false;
case AsmToken::String:
case AsmToken::Identifier: {
// This is a symbol reference.
- MCSymbol *Sym = CreateSymbol(Lexer.getTok().getIdentifier());
- Lexer.Lex(); // Eat identifier.
+ MCSymbol *Sym = CreateSymbol(getTok().getIdentifier());
+ EndLoc = Lexer.getLoc();
+ Lex(); // Eat identifier.
// If this is an absolute variable reference, substitute it now to preserve
// semantics in the face of reassignment.
@@ -245,33 +285,39 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res) {
return false;
}
case AsmToken::Integer:
- Res = MCConstantExpr::Create(Lexer.getTok().getIntVal(), getContext());
- Lexer.Lex(); // Eat token.
+ Res = MCConstantExpr::Create(getTok().getIntVal(), getContext());
+ EndLoc = Lexer.getLoc();
+ Lex(); // Eat token.
return false;
case AsmToken::LParen:
- Lexer.Lex(); // Eat the '('.
- return ParseParenExpr(Res);
+ Lex(); // Eat the '('.
+ return ParseParenExpr(Res, EndLoc);
case AsmToken::Minus:
- Lexer.Lex(); // Eat the operator.
- if (ParsePrimaryExpr(Res))
+ Lex(); // Eat the operator.
+ if (ParsePrimaryExpr(Res, EndLoc))
return true;
Res = MCUnaryExpr::CreateMinus(Res, getContext());
return false;
case AsmToken::Plus:
- Lexer.Lex(); // Eat the operator.
- if (ParsePrimaryExpr(Res))
+ Lex(); // Eat the operator.
+ if (ParsePrimaryExpr(Res, EndLoc))
return true;
Res = MCUnaryExpr::CreatePlus(Res, getContext());
return false;
case AsmToken::Tilde:
- Lexer.Lex(); // Eat the operator.
- if (ParsePrimaryExpr(Res))
+ Lex(); // Eat the operator.
+ if (ParsePrimaryExpr(Res, EndLoc))
return true;
Res = MCUnaryExpr::CreateNot(Res, getContext());
return false;
}
}
+bool AsmParser::ParseExpression(const MCExpr *&Res) {
+ SMLoc EndLoc;
+ return ParseExpression(Res, EndLoc);
+}
+
/// ParseExpression - Parse an expression and return it.
///
/// expr ::= expr +,- expr -> lowest.
@@ -279,14 +325,14 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res) {
/// expr ::= expr *,/,%,<<,>> expr -> highest.
/// expr ::= primaryexpr
///
-bool AsmParser::ParseExpression(const MCExpr *&Res) {
+bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
Res = 0;
- return ParsePrimaryExpr(Res) ||
- ParseBinOpRHS(1, Res);
+ return ParsePrimaryExpr(Res, EndLoc) ||
+ ParseBinOpRHS(1, Res, EndLoc);
}
-bool AsmParser::ParseParenExpression(const MCExpr *&Res) {
- if (ParseParenExpr(Res))
+bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
+ if (ParseParenExpr(Res, EndLoc))
return true;
return false;
@@ -381,7 +427,8 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K,
/// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
/// Res contains the LHS of the expression on input.
-bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res) {
+bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
+ SMLoc &EndLoc) {
while (1) {
MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
@@ -391,18 +438,18 @@ bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res) {
if (TokPrec < Precedence)
return false;
- Lexer.Lex();
+ Lex();
// Eat the next primary expression.
const MCExpr *RHS;
- if (ParsePrimaryExpr(RHS)) return true;
+ if (ParsePrimaryExpr(RHS, EndLoc)) return true;
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
MCBinaryExpr::Opcode Dummy;
unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
if (TokPrec < NextTokPrec) {
- if (ParseBinOpRHS(Precedence+1, RHS)) return true;
+ if (ParseBinOpRHS(Precedence+1, RHS, EndLoc)) return true;
}
// Merge LHS and RHS according to operator.
@@ -419,12 +466,12 @@ bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res) {
/// ::= Label* Identifier OperandList* EndOfStatement
bool AsmParser::ParseStatement() {
if (Lexer.is(AsmToken::EndOfStatement)) {
- Lexer.Lex();
+ Lex();
return false;
}
// Statements always start with an identifier.
- AsmToken ID = Lexer.getTok();
+ AsmToken ID = getTok();
SMLoc IDLoc = ID.getLoc();
StringRef IDVal;
if (ParseIdentifier(IDVal))
@@ -436,7 +483,7 @@ bool AsmParser::ParseStatement() {
switch (Lexer.getKind()) {
case AsmToken::Colon: {
// identifier ':' -> Label.
- Lexer.Lex();
+ Lex();
// Diagnose attempt to use a variable as a label.
//
@@ -455,7 +502,7 @@ bool AsmParser::ParseStatement() {
case AsmToken::Equal:
// identifier '=' ... -> assignment statement
- Lexer.Lex();
+ Lex();
return ParseAssignment(IDVal);
@@ -727,7 +774,7 @@ bool AsmParser::ParseStatement() {
return TokError("unexpected token in argument list");
// Eat the end of statement marker.
- Lexer.Lex();
+ Lex();
MCInst Inst;
@@ -764,7 +811,7 @@ bool AsmParser::ParseAssignment(const StringRef &Name) {
return TokError("unexpected token in assignment");
// Eat the end of statement marker.
- Lexer.Lex();
+ Lex();
// Validate that the LHS is allowed to be a variable (either it has not been
// used as a symbol, or it is an absolute symbol).
@@ -800,9 +847,9 @@ bool AsmParser::ParseIdentifier(StringRef &Res) {
Lexer.isNot(AsmToken::String))
return true;
- Res = Lexer.getTok().getIdentifier();
+ Res = getTok().getIdentifier();
- Lexer.Lex(); // Consume the identifier token.
+ Lex(); // Consume the identifier token.
return false;
}
@@ -817,7 +864,7 @@ bool AsmParser::ParseDirectiveSet() {
if (Lexer.isNot(AsmToken::Comma))
return TokError("unexpected token in '.set'");
- Lexer.Lex();
+ Lex();
return ParseAssignment(Name);
}
@@ -845,10 +892,10 @@ bool AsmParser::ParseDirectiveDarwinSection() {
StringRef EOL = Lexer.LexUntilEndOfStatement();
SectionSpec.append(EOL.begin(), EOL.end());
- Lexer.Lex();
+ Lex();
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.section' directive");
- Lexer.Lex();
+ Lex();
StringRef Segment, Section;
@@ -873,7 +920,7 @@ bool AsmParser::ParseDirectiveSectionSwitch(const char *Segment,
unsigned StubSize) {
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in section switching directive");
- Lexer.Lex();
+ Lex();
// FIXME: Arch specific.
Out.SwitchSection(getMachOSection(Segment, Section, TAA, StubSize,
@@ -897,7 +944,7 @@ bool AsmParser::ParseEscapedString(std::string &Data) {
assert(Lexer.is(AsmToken::String) && "Unexpected current token!");
Data = "";
- StringRef Str = Lexer.getTok().getStringContents();
+ StringRef Str = getTok().getStringContents();
for (unsigned i = 0, e = Str.size(); i != e; ++i) {
if (Str[i] != '\\') {
Data += Str[i];
@@ -963,22 +1010,22 @@ bool AsmParser::ParseDirectiveAscii(bool ZeroTerminated) {
if (ParseEscapedString(Data))
return true;
- Out.EmitBytes(Data);
+ Out.EmitBytes(Data, DEFAULT_ADDRSPACE);
if (ZeroTerminated)
- Out.EmitBytes(StringRef("\0", 1));
+ Out.EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE);
- Lexer.Lex();
+ Lex();
if (Lexer.is(AsmToken::EndOfStatement))
break;
if (Lexer.isNot(AsmToken::Comma))
return TokError("unexpected token in '.ascii' or '.asciz' directive");
- Lexer.Lex();
+ Lex();
}
}
- Lexer.Lex();
+ Lex();
return false;
}
@@ -992,7 +1039,7 @@ bool AsmParser::ParseDirectiveValue(unsigned Size) {
if (ParseExpression(Value))
return true;
- Out.EmitValue(Value, Size);
+ Out.EmitValue(Value, Size, DEFAULT_ADDRSPACE);
if (Lexer.is(AsmToken::EndOfStatement))
break;
@@ -1000,11 +1047,11 @@ bool AsmParser::ParseDirectiveValue(unsigned Size) {
// FIXME: Improve diagnostic.
if (Lexer.isNot(AsmToken::Comma))
return TokError("unexpected token in directive");
- Lexer.Lex();
+ Lex();
}
}
- Lexer.Lex();
+ Lex();
return false;
}
@@ -1020,7 +1067,7 @@ bool AsmParser::ParseDirectiveSpace() {
if (Lexer.isNot(AsmToken::EndOfStatement)) {
if (Lexer.isNot(AsmToken::Comma))
return TokError("unexpected token in '.space' directive");
- Lexer.Lex();
+ Lex();
if (ParseAbsoluteExpression(FillExpr))
return true;
@@ -1031,14 +1078,13 @@ bool AsmParser::ParseDirectiveSpace() {
return TokError("unexpected token in '.space' directive");
}
- Lexer.Lex();
+ Lex();
if (NumBytes <= 0)
return TokError("invalid number of bytes in '.space' directive");
// FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
- for (uint64_t i = 0, e = NumBytes; i != e; ++i)
- Out.EmitValue(MCConstantExpr::Create(FillExpr, getContext()), 1);
+ Out.EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE);
return false;
}
@@ -1052,7 +1098,7 @@ bool AsmParser::ParseDirectiveFill() {
if (Lexer.isNot(AsmToken::Comma))
return TokError("unexpected token in '.fill' directive");
- Lexer.Lex();
+ Lex();
int64_t FillSize;
if (ParseAbsoluteExpression(FillSize))
@@ -1060,7 +1106,7 @@ bool AsmParser::ParseDirectiveFill() {
if (Lexer.isNot(AsmToken::Comma))
return TokError("unexpected token in '.fill' directive");
- Lexer.Lex();
+ Lex();
int64_t FillExpr;
if (ParseAbsoluteExpression(FillExpr))
@@ -1069,13 +1115,14 @@ bool AsmParser::ParseDirectiveFill() {
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.fill' directive");
- Lexer.Lex();
+ Lex();
if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8)
return TokError("invalid '.fill' size, expected 1, 2, 4, or 8");
for (uint64_t i = 0, e = NumValues; i != e; ++i)
- Out.EmitValue(MCConstantExpr::Create(FillExpr, getContext()), FillSize);
+ Out.EmitValue(MCConstantExpr::Create(FillExpr, getContext()), FillSize,
+ DEFAULT_ADDRSPACE);
return false;
}
@@ -1093,7 +1140,7 @@ bool AsmParser::ParseDirectiveOrg() {
if (Lexer.isNot(AsmToken::EndOfStatement)) {
if (Lexer.isNot(AsmToken::Comma))
return TokError("unexpected token in '.org' directive");
- Lexer.Lex();
+ Lex();
if (ParseAbsoluteExpression(FillExpr))
return true;
@@ -1102,7 +1149,7 @@ bool AsmParser::ParseDirectiveOrg() {
return TokError("unexpected token in '.org' directive");
}
- Lexer.Lex();
+ Lex();
// FIXME: Only limited forms of relocatable expressions are accepted here, it
// has to be relative to the current section.
@@ -1126,7 +1173,7 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
if (Lexer.isNot(AsmToken::EndOfStatement)) {
if (Lexer.isNot(AsmToken::Comma))
return TokError("unexpected token in directive");
- Lexer.Lex();
+ Lex();
// The fill expression can be omitted while specifying a maximum number of
// alignment bytes, e.g:
@@ -1140,7 +1187,7 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
if (Lexer.isNot(AsmToken::EndOfStatement)) {
if (Lexer.isNot(AsmToken::Comma))
return TokError("unexpected token in directive");
- Lexer.Lex();
+ Lex();
MaxBytesLoc = Lexer.getLoc();
if (ParseAbsoluteExpression(MaxBytesToFill))
@@ -1151,7 +1198,7 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
}
}
- Lexer.Lex();
+ Lex();
if (!HasFillExpr) {
// FIXME: Sometimes fill with nop.
@@ -1209,11 +1256,11 @@ bool AsmParser::ParseDirectiveSymbolAttribute(MCStreamer::SymbolAttr Attr) {
if (Lexer.isNot(AsmToken::Comma))
return TokError("unexpected token in directive");
- Lexer.Lex();
+ Lex();
}
}
- Lexer.Lex();
+ Lex();
return false;
}
@@ -1229,7 +1276,7 @@ bool AsmParser::ParseDirectiveDarwinSymbolDesc() {
if (Lexer.isNot(AsmToken::Comma))
return TokError("unexpected token in '.desc' directive");
- Lexer.Lex();
+ Lex();
SMLoc DescLoc = Lexer.getLoc();
int64_t DescValue;
@@ -1239,7 +1286,7 @@ bool AsmParser::ParseDirectiveDarwinSymbolDesc() {
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.desc' directive");
- Lexer.Lex();
+ Lex();
// Set the n_desc field of this Symbol to this DescValue
Out.EmitSymbolDesc(Sym, DescValue);
@@ -1260,7 +1307,7 @@ bool AsmParser::ParseDirectiveComm(bool IsLocal) {
if (Lexer.isNot(AsmToken::Comma))
return TokError("unexpected token in directive");
- Lexer.Lex();
+ Lex();
int64_t Size;
SMLoc SizeLoc = Lexer.getLoc();
@@ -1270,16 +1317,23 @@ bool AsmParser::ParseDirectiveComm(bool IsLocal) {
int64_t Pow2Alignment = 0;
SMLoc Pow2AlignmentLoc;
if (Lexer.is(AsmToken::Comma)) {
- Lexer.Lex();
+ Lex();
Pow2AlignmentLoc = Lexer.getLoc();
if (ParseAbsoluteExpression(Pow2Alignment))
return true;
+
+ // If this target takes alignments in bytes (not log) validate and convert.
+ if (Lexer.getMAI().getAlignmentIsInBytes()) {
+ if (!isPowerOf2_64(Pow2Alignment))
+ return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
+ Pow2Alignment = Log2_64(Pow2Alignment);
+ }
}
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.comm' or '.lcomm' directive");
- Lexer.Lex();
+ Lex();
// NOTE: a size of zero for a .comm should create a undefined symbol
// but a size of .lcomm creates a bss symbol of size zero.
@@ -1319,18 +1373,18 @@ bool AsmParser::ParseDirectiveDarwinZerofill() {
if (Lexer.isNot(AsmToken::Identifier))
return TokError("expected segment name after '.zerofill' directive");
- StringRef Segment = Lexer.getTok().getString();
- Lexer.Lex();
+ StringRef Segment = getTok().getString();
+ Lex();
if (Lexer.isNot(AsmToken::Comma))
return TokError("unexpected token in directive");
- Lexer.Lex();
+ Lex();
if (Lexer.isNot(AsmToken::Identifier))
return TokError("expected section name after comma in '.zerofill' "
"directive");
- StringRef Section = Lexer.getTok().getString();
- Lexer.Lex();
+ StringRef Section = getTok().getString();
+ Lex();
// If this is the end of the line all that was wanted was to create the
// the section but with no symbol.
@@ -1344,19 +1398,19 @@ bool AsmParser::ParseDirectiveDarwinZerofill() {
if (Lexer.isNot(AsmToken::Comma))
return TokError("unexpected token in directive");
- Lexer.Lex();
+ Lex();
if (Lexer.isNot(AsmToken::Identifier))
return TokError("expected identifier in directive");
// handle the identifier as the key symbol.
SMLoc IDLoc = Lexer.getLoc();
- MCSymbol *Sym = CreateSymbol(Lexer.getTok().getString());
- Lexer.Lex();
+ MCSymbol *Sym = CreateSymbol(getTok().getString());
+ Lex();
if (Lexer.isNot(AsmToken::Comma))
return TokError("unexpected token in directive");
- Lexer.Lex();
+ Lex();
int64_t Size;
SMLoc SizeLoc = Lexer.getLoc();
@@ -1366,7 +1420,7 @@ bool AsmParser::ParseDirectiveDarwinZerofill() {
int64_t Pow2Alignment = 0;
SMLoc Pow2AlignmentLoc;
if (Lexer.is(AsmToken::Comma)) {
- Lexer.Lex();
+ Lex();
Pow2AlignmentLoc = Lexer.getLoc();
if (ParseAbsoluteExpression(Pow2Alignment))
return true;
@@ -1375,7 +1429,7 @@ bool AsmParser::ParseDirectiveDarwinZerofill() {
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.zerofill' directive");
- Lexer.Lex();
+ Lex();
if (Size < 0)
return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
@@ -1408,7 +1462,7 @@ bool AsmParser::ParseDirectiveDarwinSubsectionsViaSymbols() {
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.subsections_via_symbols' directive");
- Lexer.Lex();
+ Lex();
Out.EmitAssemblerFlag(MCStreamer::SubsectionsViaSymbols);
@@ -1426,15 +1480,15 @@ bool AsmParser::ParseDirectiveAbort() {
if (Lexer.isNot(AsmToken::String))
return TokError("expected string in '.abort' directive");
- Str = Lexer.getTok().getString();
+ Str = getTok().getString();
- Lexer.Lex();
+ Lex();
}
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.abort' directive");
- Lexer.Lex();
+ Lex();
// FIXME: Handle here.
if (Str.empty())
@@ -1457,7 +1511,7 @@ bool AsmParser::ParseDirectiveDarwinLsym() {
if (Lexer.isNot(AsmToken::Comma))
return TokError("unexpected token in '.lsym' directive");
- Lexer.Lex();
+ Lex();
const MCExpr *Value;
SMLoc StartLoc = Lexer.getLoc();
@@ -1467,7 +1521,7 @@ bool AsmParser::ParseDirectiveDarwinLsym() {
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.lsym' directive");
- Lexer.Lex();
+ Lex();
// We don't currently support this directive.
//
@@ -1482,9 +1536,9 @@ bool AsmParser::ParseDirectiveInclude() {
if (Lexer.isNot(AsmToken::String))
return TokError("expected string in '.include' directive");
- std::string Filename = Lexer.getTok().getString();
+ std::string Filename = getTok().getString();
SMLoc IncludeLoc = Lexer.getLoc();
- Lexer.Lex();
+ Lex();
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.include' directive");
@@ -1494,10 +1548,10 @@ bool AsmParser::ParseDirectiveInclude() {
// Attempt to switch the lexer to the included file before consuming the end
// of statement to avoid losing it when we switch.
- if (Lexer.EnterIncludeFile(Filename)) {
- Lexer.PrintMessage(IncludeLoc,
- "Could not find include file '" + Filename + "'",
- "error");
+ if (EnterIncludeFile(Filename)) {
+ PrintMessage(IncludeLoc,
+ "Could not find include file '" + Filename + "'",
+ "error");
return true;
}
@@ -1510,12 +1564,12 @@ bool AsmParser::ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump) {
if (Lexer.isNot(AsmToken::String))
return TokError("expected string in '.dump' or '.load' directive");
- Lexer.Lex();
+ Lex();
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.dump' or '.load' directive");
- Lexer.Lex();
+ Lex();
// FIXME: If/when .dump and .load are implemented they will be done in the
// the assembly parser and not have any need for an MCStreamer API.
@@ -1531,7 +1585,7 @@ bool AsmParser::ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump) {
/// ::= .if expression
bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
// Consume the identifier that was the .if directive
- Lexer.Lex();
+ Lex();
TheCondStack.push_back(TheCondState);
TheCondState.TheCond = AsmCond::IfCond;
@@ -1546,7 +1600,7 @@ bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.if' directive");
- Lexer.Lex();
+ Lex();
TheCondState.CondMet = ExprValue;
TheCondState.Ignore = !TheCondState.CondMet;
@@ -1565,7 +1619,7 @@ bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
TheCondState.TheCond = AsmCond::ElseIfCond;
// Consume the identifier that was the .elseif directive
- Lexer.Lex();
+ Lex();
bool LastIgnoreState = false;
if (!TheCondStack.empty())
@@ -1582,7 +1636,7 @@ bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.elseif' directive");
- Lexer.Lex();
+ Lex();
TheCondState.CondMet = ExprValue;
TheCondState.Ignore = !TheCondState.CondMet;
}
@@ -1594,12 +1648,12 @@ bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
/// ::= .else
bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
// Consume the identifier that was the .else directive
- Lexer.Lex();
+ Lex();
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.else' directive");
- Lexer.Lex();
+ Lex();
if (TheCondState.TheCond != AsmCond::IfCond &&
TheCondState.TheCond != AsmCond::ElseIfCond)
@@ -1621,12 +1675,12 @@ bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
/// ::= .endif
bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
// Consume the identifier that was the .endif directive
- Lexer.Lex();
+ Lex();
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.endif' directive");
- Lexer.Lex();
+ Lex();
if ((TheCondState.TheCond == AsmCond::NoCond) ||
TheCondStack.empty())
@@ -1646,8 +1700,8 @@ bool AsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
// FIXME: I'm not sure what this is.
int64_t FileNumber = -1;
if (Lexer.is(AsmToken::Integer)) {
- FileNumber = Lexer.getTok().getIntVal();
- Lexer.Lex();
+ FileNumber = getTok().getIntVal();
+ Lex();
if (FileNumber < 1)
return TokError("file number less than one");
@@ -1656,8 +1710,8 @@ bool AsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
if (Lexer.isNot(AsmToken::String))
return TokError("unexpected token in '.file' directive");
- StringRef ATTRIBUTE_UNUSED FileName = Lexer.getTok().getString();
- Lexer.Lex();
+ StringRef ATTRIBUTE_UNUSED FileName = getTok().getString();
+ Lex();
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.file' directive");
@@ -1674,9 +1728,9 @@ bool AsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) {
if (Lexer.isNot(AsmToken::Integer))
return TokError("unexpected token in '.line' directive");
- int64_t LineNumber = Lexer.getTok().getIntVal();
+ int64_t LineNumber = getTok().getIntVal();
(void) LineNumber;
- Lexer.Lex();
+ Lex();
// FIXME: Do something with the .line.
}
@@ -1695,26 +1749,26 @@ bool AsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
return TokError("unexpected token in '.loc' directive");
// FIXME: What are these fields?
- int64_t FileNumber = Lexer.getTok().getIntVal();
+ int64_t FileNumber = getTok().getIntVal();
(void) FileNumber;
// FIXME: Validate file.
- Lexer.Lex();
+ Lex();
if (Lexer.isNot(AsmToken::EndOfStatement)) {
if (Lexer.isNot(AsmToken::Integer))
return TokError("unexpected token in '.loc' directive");
- int64_t Param2 = Lexer.getTok().getIntVal();
+ int64_t Param2 = getTok().getIntVal();
(void) Param2;
- Lexer.Lex();
+ Lex();
if (Lexer.isNot(AsmToken::EndOfStatement)) {
if (Lexer.isNot(AsmToken::Integer))
return TokError("unexpected token in '.loc' directive");
- int64_t Param3 = Lexer.getTok().getIntVal();
+ int64_t Param3 = getTok().getIntVal();
(void) Param3;
- Lexer.Lex();
+ Lex();
// FIXME: Do something with the .loc.
}
diff --git a/tools/llvm-mc/AsmParser.h b/tools/llvm-mc/AsmParser.h
index 171dfcd..9336d35 100644
--- a/tools/llvm-mc/AsmParser.h
+++ b/tools/llvm-mc/AsmParser.h
@@ -25,21 +25,28 @@
namespace llvm {
class AsmCond;
+class AsmToken;
class MCContext;
class MCExpr;
class MCInst;
class MCStreamer;
class MCAsmInfo;
class MCValue;
+class SourceMgr;
class TargetAsmParser;
class Twine;
class AsmParser : public MCAsmParser {
-private:
+private:
AsmLexer Lexer;
MCContext &Ctx;
MCStreamer &Out;
+ SourceMgr &SrcMgr;
TargetAsmParser *TargetParser;
+
+ /// This is the current buffer index we're lexing from as managed by the
+ /// SourceMgr object.
+ int CurBuffer;
AsmCond TheCondState;
std::vector<AsmCond> TheCondStack;
@@ -79,8 +86,11 @@ public:
virtual void Warning(SMLoc L, const Twine &Meg);
virtual bool Error(SMLoc L, const Twine &Msg);
- virtual bool ParseExpression(const MCExpr *&Res);
- virtual bool ParseParenExpression(const MCExpr *&Res);
+ const AsmToken &Lex();
+
+ bool ParseExpression(const MCExpr *&Res);
+ virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc);
+ virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc);
virtual bool ParseAbsoluteExpression(int64_t &Res);
/// }
@@ -99,15 +109,20 @@ private:
bool TokError(const char *Msg);
+ void PrintMessage(SMLoc Loc, const std::string &Msg, const char *Type) const;
+
+ /// EnterIncludeFile - Enter the specified file. This returns true on failure.
+ bool EnterIncludeFile(const std::string &Filename);
+
bool ParseConditionalAssemblyDirectives(StringRef Directive,
SMLoc DirectiveLoc);
void EatToEndOfStatement();
bool ParseAssignment(const StringRef &Name);
- bool ParsePrimaryExpr(const MCExpr *&Res);
- bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res);
- bool ParseParenExpr(const MCExpr *&Res);
+ bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc);
+ bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
+ bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
/// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
/// and set \arg Res to the identifier contents.
diff --git a/tools/llvm-mc/CMakeLists.txt b/tools/llvm-mc/CMakeLists.txt
index 46c5c6b..49c2932 100644
--- a/tools/llvm-mc/CMakeLists.txt
+++ b/tools/llvm-mc/CMakeLists.txt
@@ -1,8 +1,6 @@
-set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support MC)
+set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support MC MCParser)
add_llvm_tool(llvm-mc
llvm-mc.cpp
- AsmLexer.cpp
- AsmParser.cpp
Disassembler.cpp
)
diff --git a/tools/llvm-mc/Makefile b/tools/llvm-mc/Makefile
index 9bfb773..5ce1a8f 100644
--- a/tools/llvm-mc/Makefile
+++ b/tools/llvm-mc/Makefile
@@ -13,12 +13,13 @@ TOOLNAME = llvm-mc
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
NO_INSTALL = 1
+CXXFLAGS = -fno-rtti
# Include this here so we can get the configuration of the targets
# that have been configured for construction. We have to do this
# early so we can set up LINK_COMPONENTS before including Makefile.rules
include $(LEVEL)/Makefile.config
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) MC support
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) MCParser MC support
include $(LLVM_SRC_ROOT)/Makefile.rules
diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp
index 30cdfba..342ae99 100644
--- a/tools/llvm-mc/llvm-mc.cpp
+++ b/tools/llvm-mc/llvm-mc.cpp
@@ -12,7 +12,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCInstPrinter.h"
@@ -28,10 +28,11 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Signals.h"
#include "llvm/Target/TargetAsmParser.h"
+#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetMachine.h" // FIXME.
#include "llvm/Target/TargetSelect.h"
-#include "AsmParser.h"
+#include "llvm/MC/MCParser/AsmParser.h"
#include "Disassembler.h"
using namespace llvm;
@@ -133,14 +134,14 @@ static int AsLexInput(const char *ProgName) {
const MCAsmInfo *MAI = TheTarget->createAsmInfo(TripleName);
assert(MAI && "Unable to create target asm info!");
- AsmLexer Lexer(SrcMgr, *MAI);
+ AsmLexer Lexer(*MAI);
bool Error = false;
while (Lexer.Lex().isNot(AsmToken::Eof)) {
switch (Lexer.getKind()) {
default:
- Lexer.PrintMessage(Lexer.getLoc(), "unknown token", "warning");
+ SrcMgr.PrintMessage(Lexer.getLoc(), "unknown token", "warning");
Error = true;
break;
case AsmToken::Error:
@@ -263,7 +264,9 @@ static int AssembleInput(const char *ProgName) {
IP.reset(TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *Out));
if (ShowEncoding)
CE.reset(TheTarget->createCodeEmitter(*TM));
- Str.reset(createAsmStreamer(Ctx, *Out, *MAI, IP.get(), CE.get()));
+ Str.reset(createAsmStreamer(Ctx, *Out, *MAI,
+ TM->getTargetData()->isLittleEndian(),
+ /*asmverbose*/true, IP.get(), CE.get()));
} else {
assert(FileType == OFT_ObjectFile && "Invalid file type!");
CE.reset(TheTarget->createCodeEmitter(*TM));
diff --git a/tools/llvm-nm/Makefile b/tools/llvm-nm/Makefile
index ecf5f8c..bdefaa6 100644
--- a/tools/llvm-nm/Makefile
+++ b/tools/llvm-nm/Makefile
@@ -13,5 +13,6 @@ LINK_COMPONENTS = archive bitreader
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-prof/Makefile b/tools/llvm-prof/Makefile
index 86eb54d..b1fd330 100644
--- a/tools/llvm-prof/Makefile
+++ b/tools/llvm-prof/Makefile
@@ -13,5 +13,6 @@ LINK_COMPONENTS = bitreader analysis
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp
index 93eb0a5..46e967a 100644
--- a/tools/lto/LTOCodeGenerator.cpp
+++ b/tools/lto/LTOCodeGenerator.cpp
@@ -32,13 +32,13 @@
#include "llvm/CodeGen/FileWriters.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/StandardPasses.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/System/Host.h"
#include "llvm/System/Program.h"
#include "llvm/System/Signals.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/SubtargetFeature.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -323,19 +323,18 @@ void LTOCodeGenerator::applyScopeRestrictions()
// mark which symbols can not be internalized
if ( !_mustPreserveSymbols.empty() ) {
- Mangler mangler(*mergedModule,
- _target->getMCAsmInfo()->getGlobalPrefix());
+ Mangler mangler(*_target->getMCAsmInfo());
std::vector<const char*> mustPreserveList;
for (Module::iterator f = mergedModule->begin(),
e = mergedModule->end(); f != e; ++f) {
if ( !f->isDeclaration()
- && _mustPreserveSymbols.count(mangler.getMangledName(f)) )
+ && _mustPreserveSymbols.count(mangler.getNameWithPrefix(f)) )
mustPreserveList.push_back(::strdup(f->getNameStr().c_str()));
}
for (Module::global_iterator v = mergedModule->global_begin(),
e = mergedModule->global_end(); v != e; ++v) {
if ( !v->isDeclaration()
- && _mustPreserveSymbols.count(mangler.getMangledName(v)) )
+ && _mustPreserveSymbols.count(mangler.getNameWithPrefix(v)) )
mustPreserveList.push_back(::strdup(v->getNameStr().c_str()));
}
passes.add(createInternalizePass(mustPreserveList));
@@ -403,14 +402,12 @@ bool LTOCodeGenerator::generateAssemblyCode(formatted_raw_ostream& out,
switch (_target->addPassesToEmitFile(*codeGenPasses, out,
TargetMachine::AssemblyFile,
CodeGenOpt::Aggressive)) {
- case FileModel::MachOFile:
- oce = AddMachOWriter(*codeGenPasses, out, *_target);
- break;
case FileModel::ElfFile:
oce = AddELFWriter(*codeGenPasses, out, *_target);
break;
case FileModel::AsmFile:
break;
+ case FileModel::MachOFile:
case FileModel::Error:
case FileModel::None:
errMsg = "target file type not supported";
diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp
index bce4162..64de668 100644
--- a/tools/lto/LTOModule.cpp
+++ b/tools/lto/LTOModule.cpp
@@ -22,12 +22,12 @@
#include "llvm/ADT/Triple.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Support/SystemUtils.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/System/Host.h"
#include "llvm/System/Path.h"
#include "llvm/System/Process.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/SubtargetFeature.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/TargetMachine.h"
@@ -320,7 +320,7 @@ void LTOModule::addDefinedSymbol(GlobalValue* def, Mangler &mangler,
return;
// string is owned by _defines
- const char* symbolName = ::strdup(mangler.getMangledName(def).c_str());
+ const char* symbolName = ::strdup(mangler.getNameWithPrefix(def).c_str());
// set alignment part log2() can have rounding errors
uint32_t align = def->getAlignment();
@@ -393,7 +393,7 @@ void LTOModule::addPotentialUndefinedSymbol(GlobalValue* decl, Mangler &mangler)
if (isa<GlobalAlias>(decl))
return;
- std::string name = mangler.getMangledName(decl);
+ std::string name = mangler.getNameWithPrefix(decl);
// we already have the symbol
if (_undefines.find(name) != _undefines.end())
@@ -439,15 +439,7 @@ void LTOModule::lazyParseSymbols()
_symbolsParsed = true;
// Use mangler to add GlobalPrefix to names to match linker names.
- Mangler mangler(*_module, _target->getMCAsmInfo()->getGlobalPrefix());
- // add chars used in ObjC method names so method names aren't mangled
- mangler.markCharAcceptable('[');
- mangler.markCharAcceptable(']');
- mangler.markCharAcceptable('(');
- mangler.markCharAcceptable(')');
- mangler.markCharAcceptable('-');
- mangler.markCharAcceptable('+');
- mangler.markCharAcceptable(' ');
+ Mangler mangler(*_target->getMCAsmInfo());
// add functions
for (Module::iterator f = _module->begin(); f != _module->end(); ++f) {
diff --git a/tools/lto/Makefile b/tools/lto/Makefile
index 3120aa5..f0bc67c 100644
--- a/tools/lto/Makefile
+++ b/tools/lto/Makefile
@@ -17,6 +17,7 @@ include $(LEVEL)/Makefile.config
LINK_LIBS_IN_SHARED = 1
SHARED_LIBRARY = 1
+CXXFLAGS = -fno-rtti
LINK_COMPONENTS := $(TARGETS_TO_BUILD) ipo scalaropts linker bitreader bitwriter
diff --git a/tools/opt/Makefile b/tools/opt/Makefile
index 726cad8..2f184a6 100644
--- a/tools/opt/Makefile
+++ b/tools/opt/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../..
TOOLNAME = opt
+CXXFLAGS = -fno-rtti
LINK_COMPONENTS := bitreader bitwriter asmparser instrumentation scalaropts ipo
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
index a636bd9..6ed8c9d 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -288,7 +288,17 @@ void AddOptimizationPasses(PassManager &MPM, FunctionPassManager &FPM,
unsigned OptLevel) {
createStandardFunctionPasses(&FPM, OptLevel);
- llvm::Pass *InliningPass = OptLevel > 1 ? createFunctionInliningPass() : 0;
+ llvm::Pass *InliningPass = 0;
+ if (DisableInline) {
+ // No inlining pass
+ } else if (OptLevel) {
+ unsigned Threshold = 200;
+ if (OptLevel > 2)
+ Threshold = 250;
+ InliningPass = createFunctionInliningPass(Threshold);
+ } else {
+ InliningPass = createAlwaysInlinerPass();
+ }
createStandardModulePasses(&MPM, OptLevel,
/*OptimizeSize=*/ false,
UnitAtATime,
@@ -373,24 +383,29 @@ int main(int argc, char **argv) {
// FIXME: outs() is not binary!
raw_ostream *Out = &outs(); // Default to printing to stdout...
if (OutputFilename != "-") {
- // Make sure that the Output file gets unlinked from the disk if we get a
- // SIGINT
- sys::RemoveFileOnSignal(sys::Path(OutputFilename));
-
- std::string ErrorInfo;
- Out = new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo,
- raw_fd_ostream::F_Binary);
- if (!ErrorInfo.empty()) {
- errs() << ErrorInfo << '\n';
- delete Out;
- return 1;
+ if (NoOutput || AnalyzeOnly) {
+ errs() << "WARNING: The -o (output filename) option is ignored when\n"
+ "the --disable-output or --analyze options are used.\n";
+ } else {
+ // Make sure that the Output file gets unlinked from the disk if we get a
+ // SIGINT
+ sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+
+ std::string ErrorInfo;
+ Out = new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo,
+ raw_fd_ostream::F_Binary);
+ if (!ErrorInfo.empty()) {
+ errs() << ErrorInfo << '\n';
+ delete Out;
+ return 1;
+ }
}
}
// If the output is set to be emitted to standard out, and standard out is a
// console, print out a warning message and refuse to do it. We don't
// impress anyone by spewing tons of binary goo to a terminal.
- if (!Force && !NoOutput && !OutputAssembly)
+ if (!Force && !NoOutput && !AnalyzeOnly && !OutputAssembly)
if (CheckBitcodeOutputToConsole(*Out, !Quiet))
NoOutput = true;
@@ -461,24 +476,26 @@ int main(int argc, char **argv) {
errs() << argv[0] << ": cannot create pass: "
<< PassInf->getPassName() << "\n";
if (P) {
- bool isBBPass = dynamic_cast<BasicBlockPass*>(P) != 0;
- bool isLPass = !isBBPass && dynamic_cast<LoopPass*>(P) != 0;
- bool isFPass = !isLPass && dynamic_cast<FunctionPass*>(P) != 0;
- bool isCGSCCPass = !isFPass && dynamic_cast<CallGraphSCCPass*>(P) != 0;
-
addPass(Passes, P);
if (AnalyzeOnly) {
- if (isBBPass)
+ switch (P->getPassKind()) {
+ case PT_BasicBlock:
Passes.add(new BasicBlockPassPrinter(PassInf));
- else if (isLPass)
+ break;
+ case PT_Loop:
Passes.add(new LoopPassPrinter(PassInf));
- else if (isFPass)
+ break;
+ case PT_Function:
Passes.add(new FunctionPassPrinter(PassInf));
- else if (isCGSCCPass)
+ break;
+ case PT_CallGraphSCC:
Passes.add(new CallGraphSCCPassPrinter(PassInf));
- else
+ break;
+ default:
Passes.add(new ModulePassPrinter(PassInf));
+ break;
+ }
}
}
@@ -517,7 +534,7 @@ int main(int argc, char **argv) {
if (!NoVerify && !VerifyEach)
Passes.add(createVerifierPass());
- // Write bitcode or assembly out to disk or outs() as the last step...
+ // Write bitcode or assembly out to disk or outs() as the last step...
if (!NoOutput && !AnalyzeOnly) {
if (OutputAssembly)
Passes.add(createPrintModulePass(Out));
diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
index dda86fb..a58a087 100644
--- a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
+++ b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
@@ -23,6 +23,9 @@
using namespace llvm;
+int dummy;
+
+#if 0
namespace {
struct FunctionEmittedEvent {
@@ -235,3 +238,4 @@ testing::Environment* const jit_env =
testing::AddGlobalTestEnvironment(new JITEnvironment);
} // anonymous namespace
+#endif
diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp
index 7f75afa..bed2d22 100644
--- a/unittests/ExecutionEngine/JIT/JITTest.cpp
+++ b/unittests/ExecutionEngine/JIT/JITTest.cpp
@@ -58,6 +58,7 @@ std::string DumpFunction(const Function *F) {
return Result;
}
+#if 0
class RecordingJITMemoryManager : public JITMemoryManager {
const OwningPtr<JITMemoryManager> Base;
public:
@@ -178,6 +179,7 @@ public:
return Base->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
}
};
+#endif
bool LoadAssemblyInto(Module *M, const char *assembly) {
SMDiagnostic Error;
@@ -195,11 +197,15 @@ class JITTest : public testing::Test {
virtual void SetUp() {
M = new Module("<main>", Context);
MP = new ExistingModuleProvider(M);
+#if 0
RJMM = new RecordingJITMemoryManager;
RJMM->setPoisonMemory(true);
+#endif
std::string Error;
TheJIT.reset(EngineBuilder(MP).setEngineKind(EngineKind::JIT)
+#if 0
.setJITMemoryManager(RJMM)
+#endif
.setErrorStr(&Error).create());
ASSERT_TRUE(TheJIT.get() != NULL) << Error;
}
@@ -211,7 +217,9 @@ class JITTest : public testing::Test {
LLVMContext Context;
Module *M; // Owned by MP.
ModuleProvider *MP; // Owned by ExecutionEngine.
+#if 0
RecordingJITMemoryManager *RJMM;
+#endif
OwningPtr<ExecutionEngine> TheJIT;
};
@@ -430,6 +438,7 @@ TEST_F(JITTest, ModuleDeletion) {
TheJIT->getPointerToFunction(func);
TheJIT->deleteModuleProvider(MP);
+#if 0
SmallPtrSet<const void*, 2> FunctionsDeallocated;
for (unsigned i = 0, e = RJMM->deallocateFunctionBodyCalls.size();
i != e; ++i) {
@@ -463,6 +472,7 @@ TEST_F(JITTest, ModuleDeletion) {
}
EXPECT_EQ(RJMM->startExceptionTableCalls.size(),
NumTablesDeallocated);
+#endif
}
// ARM and PPC still emit stubs for calls since the target may be too far away
@@ -497,14 +507,18 @@ TEST_F(JITTest, NoStubs) {
// We should now allocate no more stubs, we have the code to foo
// and the existing stub for bar.
+#if 0
int stubsBefore = RJMM->stubsAllocated;
+#endif
Function *func = M->getFunction("main");
TheJIT->getPointerToFunction(func);
Function *bar = M->getFunction("bar");
TheJIT->getPointerToFunction(bar);
+#if 0
ASSERT_EQ(stubsBefore, RJMM->stubsAllocated);
+#endif
}
#endif // !ARM && !PPC
diff --git a/unittests/Support/System.cpp b/unittests/Support/System.cpp
new file mode 100644
index 0000000..b3dd17d
--- /dev/null
+++ b/unittests/Support/System.cpp
@@ -0,0 +1,16 @@
+//===- llvm/unittest/Support/System.cpp - System tests --===//
+#include "gtest/gtest.h"
+#include "llvm/System/TimeValue.h"
+#include <time.h>
+
+using namespace llvm;
+namespace {
+class SystemTest : public ::testing::Test {
+};
+
+TEST_F(SystemTest, TimeValue) {
+ sys::TimeValue now = sys::TimeValue::now();
+ time_t now_t = time(NULL);
+ EXPECT_TRUE(abs(now_t - now.toEpochTime()) < 2);
+}
+}
diff --git a/unittests/VMCore/PassManagerTest.cpp b/unittests/VMCore/PassManagerTest.cpp
index cb8f9eb..092ce3d 100644
--- a/unittests/VMCore/PassManagerTest.cpp
+++ b/unittests/VMCore/PassManagerTest.cpp
@@ -32,6 +32,10 @@
#include "llvm/Assembly/PrintModulePass.h"
#include "gtest/gtest.h"
+int dummy;
+
+#if 0
+
namespace llvm {
namespace {
// ND = no deps
@@ -525,3 +529,4 @@ namespace llvm {
}
}
+#endif
diff --git a/utils/GetSourceVersion b/utils/GetSourceVersion
new file mode 100755
index 0000000..b25f2f9
--- /dev/null
+++ b/utils/GetSourceVersion
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+usage() {
+ echo "usage: $0 <source root>"
+ echo " Prints the source control revision of the given source directory,"
+ echo " the exact format of the revision string depends on the source "
+ echo " control system. If the source control system isn't known, the output"
+ echo " is empty and the exit code is 1."
+ exit 1
+}
+
+if [ $# != 1 ] || [ ! -d $1 ]; then
+ usage;
+fi
+
+cd $1
+if [ -d .svn ]; then
+ svnversion
+elif [ -d .git/svn ]; then
+ git svn info | grep 'Revision:' | cut -d: -f2-
+elif [ -d .git ]; then
+ git log -1 --pretty=format:%H
+else
+ exit 1;
+fi
+
+exit 0
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp
index 019908b..ce1521d 100644
--- a/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/utils/TableGen/AsmMatcherEmitter.cpp
@@ -465,6 +465,10 @@ struct InstructionInfo {
if (Operands.size() != RHS.Operands.size())
return false;
+ // Otherwise, make sure the ordering of the two instructions is unambiguous
+ // by checking that either (a) a token or operand kind discriminates them,
+ // or (b) the ordering among equivalent kinds is consistent.
+
// Tokens and operand kinds are unambiguous (assuming a correct target
// specific parser).
for (unsigned i = 0, e = Operands.size(); i != e; ++i)
@@ -1386,9 +1390,7 @@ static void EmitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser,
"return " + utostr(i + 1) + ";"));
}
- OS << "unsigned " << Target.getName()
- << AsmParser->getValueAsString("AsmParserClassName")
- << "::MatchRegisterName(const StringRef &Name) {\n";
+ OS << "static unsigned MatchRegisterName(const StringRef &Name) {\n";
EmitStringMatcher("Name", Matches, OS);
@@ -1447,6 +1449,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
// Emit the function to match a register name to number.
EmitMatchRegisterName(Target, AsmParser, OS);
+
+ OS << "#ifndef REGISTERS_ONLY\n\n";
// Generate the unified function to convert operands into an MCInst.
EmitConvertToMCInst(Target, Info.Instructions, OS);
@@ -1546,4 +1550,6 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " return true;\n";
OS << "}\n\n";
+
+ OS << "#endif // REGISTERS_ONLY\n";
}
diff --git a/utils/buildit/build_llvm b/utils/buildit/build_llvm
index 25f6554..1fa3fdf 100755
--- a/utils/buildit/build_llvm
+++ b/utils/buildit/build_llvm
@@ -57,25 +57,20 @@ DARWIN_VERS=`uname -r | sed 's/\..*//'`
echo DARWIN_VERS = $DARWIN_VERS
if [ "x$RC_ProjectName" = "xllvmCore_Embedded" ]; then
- DT_HOME=$DEST_DIR/Developer/Platforms/iPhoneOS.platform/Developer/usr
- DEST_ROOT="/Developer/Platforms/iPhoneOS.platform/Developer$DEST_ROOT"
-elif [ "x$RC_ProjectName" = "xllvmCore_EmbeddedHosted" ]; then
- DT_HOME=$DEST_DIR/usr
- DEST_ROOT="/Developer$DEST_ROOT"
+ DEST_DIR="$DEST_DIR/Developer/Platforms/iPhoneOS.platform"
+ mkdir -p "$DEST_DIR"
+fi
+
+DEVELOPER_DIR="${DEVELOPER_DIR-Developer}"
+if [ "x$RC_ProjectName" = "xllvmCore_EmbeddedHosted" ]; then
+ DT_HOME="$DEST_DIR/usr"
HOST_SDKROOT=$SDKROOT
else
- DT_HOME=$DEST_DIR/Developer/usr
- DEST_ROOT="/Developer$DEST_ROOT"
-fi
-if [ "x$DEVELOPER_BIN" != "x" ]; then
- if [ "x$RC_ProjectName" = "xllvmCore_Embedded" ]; then
- DT_HOME=$DEST_DIR/Developer/Platforms/iPhoneOS.platform/$DEVELOPER_DIR/usr
- else
- DT_HOME=$DEST_DIR/$DEVELOPER_DIR/usr
- fi
- DEST_ROOT="/$DEVELOPER_DIR$DEST_ROOT"
+ DT_HOME="$DEST_DIR/$DEVELOPER_DIR/usr"
fi
+DEST_ROOT="/$DEVELOPER_DIR$DEST_ROOT"
+
################################################################################
# Run the build.
@@ -350,7 +345,7 @@ find $DEST_DIR -name html.tar.gz -exec rm {} \;
cd $DEST_DIR
mkdir -p ./usr/lib/
cd usr/lib
-ln -s ../../Developer/usr/lib/libLTO.dylib ./libLTO.dylib
+ln -s ../../$DEVELOPER_DIR/usr/lib/libLTO.dylib ./libLTO.dylib
################################################################################
# w00t! Done!
diff --git a/utils/lit/lit/Test.py b/utils/lit/lit/Test.py
index 1f6556b..db2e032 100644
--- a/utils/lit/lit/Test.py
+++ b/utils/lit/lit/Test.py
@@ -70,7 +70,7 @@ class Test:
self.elapsed = elapsed
def getFullName(self):
- return self.suite.config.name + '::' + '/'.join(self.path_in_suite)
+ return self.suite.config.name + ' :: ' + '/'.join(self.path_in_suite)
def getSourcePath(self):
return self.suite.getSourcePath(self.path_in_suite)
diff --git a/utils/llvm.grm b/utils/llvm.grm
index 86a707a..4499d4b 100644
--- a/utils/llvm.grm
+++ b/utils/llvm.grm
@@ -161,7 +161,6 @@ FuncAttr ::= noreturn
| signext
| readnone
| readonly
- | inlinehint
| noinline
| alwaysinline
| optsize
diff --git a/utils/mkpatch b/utils/mkpatch
index d256d98..278a241 100755
--- a/utils/mkpatch
+++ b/utils/mkpatch
@@ -23,8 +23,8 @@ echo "mkpatch: Generating differences on all directories"
svn diff -x -u >> "$NAME".patch.raw 2>&1 \
autoconf docs utils include lib/System lib/Support lib/VMCore lib/AsmParser \
lib/Bitcode lib/Analysis lib/Transforms lib/CodeGen lib/Target \
- lib/ExecutionEngine lib/Debugger lib/Linker \
- tools test unittests runtime projects examples win32 Xcode
+ lib/ExecutionEngine lib/Linker \
+ tools test unittests runtime projects examples Xcode
echo "mkpatch: Removing cruft from the patch file"
sed -e '/^[?] .*/d' -e '/^cvs diff: Diffing/d' "$NAME".patch.raw | awk '\
diff --git a/utils/vim/llvm.vim b/utils/vim/llvm.vim
index 6e4a207..48a4c68 100644
--- a/utils/vim/llvm.vim
+++ b/utils/vim/llvm.vim
@@ -51,7 +51,7 @@ syn keyword llvmKeyword volatile fastcc coldcc cc ccc
syn keyword llvmKeyword x86_stdcallcc x86_fastcallcc
syn keyword llvmKeyword signext zeroext inreg sret nounwind noreturn
syn keyword llvmKeyword nocapture byval nest readnone readonly noalias
-syn keyword llvmKeyword inlinehint noinline alwaysinline optsize ssp sspreq
+syn keyword llvmKeyword noinline alwaysinline optsize ssp sspreq
syn keyword llvmKeyword noredzone noimplicitfloat naked
syn keyword llvmKeyword module asm align tail to
syn keyword llvmKeyword addrspace section alias sideeffect c gc
OpenPOWER on IntegriCloud